Ruby on Rails:经历挫折的 has_many

发布于 2024-09-01 07:20:07 字数 1176 浏览 6 评论 0原文

我在 has_many through 上遇到了一个令人沮丧的问题:即在保存之前不会创建 through 模型。不幸的是,我需要在保存父模型之前设置这些模型的数据。

这是松散的设置:

class Wtf < ActiveRecord::Base
  belongs_to :foo
  belongs_to :bar
end

class Bar < ActiveRecord::Base
  has_many :wtfs
  has_many :foos, :through => :wtfs
end


class Foo < ActiveRecord::Base
  has_many :wtfs
  has_many :bars, :through => :wtfs

  def after_initialize
    Bar.all.each do |bar|
      bars << bar
    end
  end

end

一切都很好,除了我需要在保存之前访问“wtf”:

<块引用>

f = Foo.new => #

f.bars => [酒吧列表]

这里是空列表

<块引用>

f.wtfs => []

f.保存! =>正确

现在我得到了东西

<块引用>

f.wtfs => [内容列表]

我什至明确地创建了 wtfs,这样做:

 def after_initialize
    Bar.all.each do |bar|
      wtfs << Wtf.new( :foo => self, :bar => bar, :data_i_need_to_set => 10)
    end
  end

这会导致填充 f.wtfs,但不会填充条形图。当我保存和检索时,我得到的 wtfs 是预期的两倍。

有人有什么想法吗?

I'm having a frustrating problem with a has_many through: namely the fact that the through models are not created until save. Unfortunately, I need to set data on these models prior to saving the parent.

Here's the loose setup:

class Wtf < ActiveRecord::Base
  belongs_to :foo
  belongs_to :bar
end

class Bar < ActiveRecord::Base
  has_many :wtfs
  has_many :foos, :through => :wtfs
end


class Foo < ActiveRecord::Base
  has_many :wtfs
  has_many :bars, :through => :wtfs

  def after_initialize
    Bar.all.each do |bar|
      bars << bar
    end
  end

end

Everything is fine except that I need to access the "wtf"'s prior to save:

f = Foo.new
=> #

f.bars
=> [list of bars]

empty list here

f.wtfs
=> []

f.save!
=> true

now I get stuff

f.wtfs
=> [list of stuff]

I even went so far as to explicitly create the wtfs doing this:

 def after_initialize
    Bar.all.each do |bar|
      wtfs << Wtf.new( :foo => self, :bar => bar, :data_i_need_to_set => 10)
    end
  end

This causes the f.wtfs to be populated, but not the bars. When I save and retrieve, I get double the expected wtfs.

Anyone have any ideas?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

怪我太投入 2024-09-08 07:20:13

您可以将填充 bar 的方法设置为 after_create,如下所示:

class Foo < ActiveRecord::Base
  has_many :wtfs
  has_many :bars, :through => :wtfs
  after_create :associate_bars

  def associate_bars
    Bar.all.each do |bar|
      bars << bar
    end
  end
end

这将使 wtfs 在调用此方法时已经创建。

You could set the method that populates bar to an after_create, like this:

class Foo < ActiveRecord::Base
  has_many :wtfs
  has_many :bars, :through => :wtfs
  after_create :associate_bars

  def associate_bars
    Bar.all.each do |bar|
      bars << bar
    end
  end
end

This would make the wtfs be already be created when this method is called.

琉璃梦幻 2024-09-08 07:20:11

您不能在 Wtf 上编写一个 before_save 处理程序来设置您需要设置的数据吗?如果需要的话,它可以访问 foo 和 bar。

Couldn't you write a before_save handler on Wtf that would set the data you need to set? It would have access to both the foo and bar, if needed.

三人与歌 2024-09-08 07:20:10

我认为您直接创建 Wtfs 的想法是正确的。我认为如果您同时设置条形,结果会很好:

def after_initialize
  Bar.all.each do |bar|
    wtfs << Wtf.new(:bar => bar, :data_i_need_to_set => 10)  # Rails should auto-assign :foo => self
    bars << bar
  end
end

Rails 应该正确保存记录,因为它们是相同的对象集合。唯一的阻力可能是,如果 Rails 没有智能地检查 Bars 集合中的新 Bar 记录是否已经具有 Wtf相关联,无论如何它都可能创建一个。尝试一下。

I think you have the right idea with creating the Wtfs directly. I think it will turn out OK if you just set the bars at the same time:

def after_initialize
  Bar.all.each do |bar|
    wtfs << Wtf.new(:bar => bar, :data_i_need_to_set => 10)  # Rails should auto-assign :foo => self
    bars << bar
  end
end

Rails should save the records correctly because they are the same collection of objects. The only drag might be that if rails doesn't have the smarts to check if a new Bar record in the bars collection already has a Wtf associated, it might create one anyway. Try it out.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文