1

我已经采用了,但我不确定为什么有些东西不起作用。

我有一个昂贵的多态关联,我只将它用于一个名为 Item 的模型。它看起来像这样:

class Item < ActiveRecord::Base
  #price
  has_one :price, :as => :pricable
  accepts_nested_attributes_for :price

  attr_accessible :price_attributes, :price, ....

我想添加到事件模型并添加了以下内容:

class Event < ActiveRecord::Base
  #price
  has_one :price, :as => :pricable
  accepts_nested_attributes_for :price
  attr_accessible :price, :price_attributes

但是,我无法设置它:

ruby-1.9.2-p290 :001 > e=Event.find(19) #ok
ruby-1.9.2-p290 :002 > e.price
Creating scope :page. Overwriting existing method Price.page.
  Price Load (0.8ms)  SELECT `prices`.* FROM `prices` WHERE `prices`.`pricable_id` = 19 AND `prices`.`pricable_type` = 'Event' LIMIT 1
 => nil 
ruby-1.9.2-p290 :003 > e.price.price=23
NoMethodError: undefined method `price=' for nil:NilClass
    from /Users/jt/.rvm/gems/ruby-1.9.2-p290/gems/activesupport-3.1.0/lib/active_support/whiny_nil.rb:48:in `method_missing'
    from (irb):3

嗯....看起来关系设置正确,并且 Event 可以通过 attr_accessible 访问价格。知道还会发生什么吗?

谢谢

4

2 回答 2

1

关系似乎定义正确,但是如果 e.price 返回 nil 则显然 e.price.price= 将不起作用并返回未定义的方法错误。您需要先构建/创建关联的价格对象:

> e = Event.find(19)
=> #<Event id: 19, ...>
> e.price
=> nil
> e.create_price(price: 23)
=> #<Price id: 1, priceable_id: 19, price: 23, ...>

或者如果您想使用嵌套属性:

> e = Event.find(19)
=> #<Event id: 19, ...>
> e.price
=> nil
> e.update_attributes(price_attributes: { price: 23 })
=> true
> e.price
=> #<Price id: 1, priceable_id: 19, price: 23, ...>
于 2012-07-16T22:34:14.773 回答
1

这就是你的模型应该是什么样子

class Price < ActiveRecord::Base
  attr_accessible :value
  belongs_to :priceable, :polymorphic => true
end

class Item < ActiveRecord::Base
   attr_accessible :name, :price_attributes
   has_one :price, :as => :priceable
   accepts_nested_attributes_for :price
end

class Event < ActiveRecord::Base
  attr_accessible :name, :price_attributes
  has_one :price, :as => :priceable
  accepts_nested_attributes_for :price
end

这就是您的价格迁移的样子

class CreatePictures < ActiveRecord::Migration
  def change
    create_table :pictures do |t|
      t.string  :name
      t.integer :imageable_id
      t.string  :imageable_type
      t.timestamps
    end
  end
end

然后你可以轻松地做这样的事情

Item.new( { name: 'John', price_attributes: { value: 80 } } )
于 2012-07-17T05:45:48.937 回答