has_many: through - добавление метаданных в сквозные отношения - PullRequest
2 голосов
/ 21 августа 2011

Мне нужно добавить метаданные об отношениях HABTM.Я хотел использовать отношение has_many: through для этого, но это не обязательно.Вот упрощенная проблема:

class Customer < ActiveRecord::Base
  has_many :customer_teddy_bears
  has_many :teddy_bears, :through => :customer_teddy_bears
end

class CustomerTeddyBear < ActiveRecrod::Base
  belongs_to :customer
  belongs_to :teddy_bear
  attr_accesible :most_favoritest # just to show it exists, boolean
end

class TeddyBear < ActiveRecord::Base
  has_many :cusomter_teddy_bears
end

Итак, что мне нужно сделать, это начать добавлять плюшевых мишек своим клиентам, плюшевые мишки - это фиксированный набор данных, скажем, fireman_bear, doctor_bear, dominatrix_bear.Любой клиент может претендовать на обладание своего рода плюшевым мишкой, но он также указывает, какой из них является самым любимым.Так как я не могу изменить модель медведей, потому что она является общей для всех клиентов, я добавляю метаданные (среди других метаданных) в CustomerTeddyBear.

Проблема в том, что следующее не работает.

customer = Customer.new # new record, not yet saved, this must be handled.
customer.teddy_bears << fireman_bear
customer.teddy_bears << doctor_bear
# now to set some metadata
favoritest_record = customer.customer_teddy_bears.select{|ctb| ctb.teddy_bear == doctor_bear}.first
favoritest_record.most_favoritest = true

Приведенный выше код не работает, поскольку записи customer_teddy_bears заполняются только во время сохранения при создании записей в базе данных.Есть ли другой механизм для этого?

Если в рельсах нет ничего "автоматизированного", мне просто нужно будет вручную управлять этим отношением, включая teddy_bears, когда я выбираю customer_teddy_bears, и используя такие методы, как

def teddy_bears
    self.customer_teddy_bears.map(&:teddy_bear)
end 

вместе с созданием вручную ассоциаций и без использования отношения: through.

обратите внимание, все это должно произойти до того, как #save будет выполнен на объекте Customer, поэтомуМне нужно установить все соответствующие метаданные, пока они находятся в памяти.

Рекомендации, которые я получил от # RubyOnRails

ctb = customer.customer_teddy_bears.build({:customer => customer, :teddy_bear => fireman_bear})
ctb2 = customer.customer_teddy_bears.build({:customer => customer, :teddy_bear => doctor_bear})
...
ctb.most_favoritest = true

Ответы [ 2 ]

1 голос
/ 21 августа 2011

Вы можете просто сделать это:

customer = Customer.new # new record, not yet saved, this must be handled.
customer.teddy_bears << fireman_bear
customer.teddy_bears << doctor_bear
customer.save

fav = CustomerTeddyBear.where(:customer_id => customer.id, :teddybear_id => doctor_bear.id)
fav.most_favoritest = true
fav.save
0 голосов
/ 22 сентября 2011

Решением, к которому я был вынужден прибегнуть, является ручное создание объекта CustomerTeddyBear и настройка customer, teddy_bear и most_favoritest. В большинстве случаев доступ осуществляется по customer.customer_teddy_bears.map(&:teddy_bear), по крайней мере, по логике, когда существует вероятность того, что запись еще не сохранена, в противном случае просто сокращен до customer.teddy_bears.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...