Fork me on GitHub
Hoopla! - now with extra whiz-bang home

Problem:

You’re getting something that says “ArgumentError: Unknown key(s): through” when you’re using a has_one :something, :through => :something else code.

Explanation:

The :through option for Rails join models is really, really handy. Basically, it allows you to turn guy.thing.places into guy.places without having to change anything in the database.

How the models would be setup to allow for the more tedious way to associate places with a guy.

    class Guy < ActiveRecord::Base
      has_one :thing
    end

    class Thing < ActiveRecord::Base
      belongs_to :guy
      has_many   :places
    end

    class Place < ActiveRecord::Base
      belongs_to :thing
    end
  

The only alteration needed is turning the Guy class into:

    class Guy < ActiveRecord::Base
      has_one  :thing
      has_many :places, :through => :thing
    end
  

For a better example of how to use :through check out Ariejan on Rails

The problem with this, and I don’t know why this is, is that this doesn’t work with has_one - only has_many! If we were to change Thing to only have one Place we would then alter the joins thusly:

    class Guy < ActiveRecord::Base
      has_one  :thing
      has_one  :place, :through => :thing
    end

    class Thing < ActiveRecord::Base
      belongs_to :guy
      has_one    :place
    end
  

And our code would fail! The above code will barf out an ArgumentError: Unknown key(s): through error.

Solution:

You can use a has_many join and make it act like a has_one join. Just use:

    class Guy < ActiveRecord::Base
      has_one  :thing
      has_many :place, :through => :thing
    end
  

Then, when you call guy.place you’ll get an array (with just one element) of places. You can use guy.place.first to replace guy.thing.place

blog comments powered by Disqus