Ruby on Rails: has_many из-за разочарований - PullRequest
0 голосов
/ 13 мая 2010

У меня неприятная проблема с помощью has_many: а именно, тот факт, что сквозные модели не создаются до сохранения. К сожалению, мне нужно установить данные для этих моделей перед сохранением родительского элемента.

Вот свободные настройки:

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.save! => правда

теперь я получаю вещи

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, но не баров. Когда я сохраняю и получаю, я получаю вдвое больше ожидаемых значений.

У кого-нибудь есть идеи?

Ответы [ 3 ]

2 голосов
/ 14 мая 2010

Я думаю, у вас есть правильная идея с созданием 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 должен правильно сохранять записи, потому что они представляют собой одну и ту же коллекцию объектов. Единственным препятствием может быть то, что если у рельсов нет умов, чтобы проверить, имеет ли новая запись Bar в коллекции баров уже ассоциированную Wtf, она все равно может создать ее. Попробуйте.

1 голос
/ 14 мая 2010

Вы можете установить метод, заполняющий 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

Это приведет к тому, что wtf будут уже созданы при вызове этого метода.

1 голос
/ 14 мая 2010

Не могли бы вы написать обработчик before_save на Wtf, который бы устанавливал данные, которые вам нужно установить? При необходимости он будет иметь доступ как к foo, так и к строке бара.

...