开发者

One-to-one polymorphic

开发者 https://www.devze.com 2023-02-13 16:43 出处:网络
I have two types of \'owner\', each of which can have one \'preference\'. This is my current set up (i.e. how I imagine a one-to-one polymorphic would work):

I have two types of 'owner', each of which can have one 'preference'.

This is my current set up (i.e. how I imagine a one-to-one polymorphic would work):

Company.rb
  has_one :pref, :as => :owner

Representative.rb
  has_one :pref, :as => :owner

Pref.rb
  belongs_to :owner, :polymorphic => true

I then try the following commands:

Company.first.owner => nil
Company.first.owner.build => error

How can I get this relationship working?


Update: details on the error

NoMethodError: undefined method `build' for nil:NilClass
from /Users/san/.rvm/gems/ruby-1.9.2-p0/gems/activesupport-3.0.1/lib/active_support/whiny_nil.rb:48:in `method_missing'
from (irb):10
from /Users/san/.rvm/gems/ruby-1.9.2-p0/gems/railties-3.0.1/lib/rails/commands/console.rb:44:in `start'
from /Users/san/.rvm/gems/ruby-1.9.2-p0/gems/railties-3.0.1/lib/rails/commands/console.rb:8:in `start'
from /Users/san/.rvm/gems/ruby-1.9.2-p0/gems/railties-3.0.1/lib/rails/commands.rb:23:in `<top (required)开发者_运维问答>'
from script/rails:6:in `require'
from script/rails:6:in `<main>'

My migration:

create_table :prefs do |t|
    t.integer :owner_id, :null => true
    t.string :owner_type, :null => true
    ...
end

Last question

# after manually building a pref to link to this representative...
Representative.first.pref => finds pref
Representative.last.pref.create => error

NoMethodError: undefined method `new' for "#<Pref:0x00000106a18ce8>":Pref
from /Users/san/.rvm/gems/ruby-1.9.2-p0/gems/activerecord-3.0.1/lib/active_record/associations/association_proxy.rb:212:in `method_missing'

This is so confusing!


Answer:

See: Using build with a has_one association in rails

Representative.last.build_pref => works


What's the error? Did you migrate your database properly? i.e.:

t.string :owner_type
t.integer :owner_id


This is kind of twisted relationship, but ... I would rather do it this way:

Remeber about :ownerable_type, :ownerable_id fields as well.

Company.rb
  has_one  :owner, :as => :ownerable

Representative.rb
  belongs_to :ownerable, :polymorphic => true

Owner.rb
  belongs_to :ownerable, :polymorphic => true

After that

Company.first.owner, should work

as well as

Owner.first.ownerable

should return the Company

In fact it seems for me better when you have:

Company.rb
  belongs_to :ownerable, :polymorphic => true

Representative.rb
  has_many :companies, :polymorphic => true, :as => :ownerable

Owner.rb
  has_many :companies, :polymorphic => true, :as => :ownerable

You could switch to has_one of course.

0

精彩评论

暂无评论...
验证码 换一张
取 消