views:

171

answers:

2

I can't seem to figure out why this association isn't working: I'm not sure how to describe the situation better than providing a code example:

Here is my application environment:

Ruby version              1.8.7 (universal-darwin10.0)
Rails version             2.3.3

And a code sample:

class Account
 has_one :subscription
 has_one :package, :through => :subscription
end

class Subscription
 belongs_to :account
 belongs_to :package
end

class Package
 has_many :subscriptions
 has_many :accounts, :through => :subscriptions
end

>> Account.first.subscription
=> #<Subscription id: 1, account_id: 25, package_id: 4>

>> Account.first.subscription.package
=> #<Package id: 4, name: "Bronze Package">

>> Package.first.accounts
=> [#<Account id: 25, subdomain: "bigbangtechnology">]

>> Package.first.subscriptions
=> [#<Subscription id: 1, account_id: 25, package_id: 4>]

>> Account.first.package
  Package Load (0.0ms)   Mysql::Error: Unknown column 'packages.account_id' in 'where clause': SELECT `packages`.* FROM `packages` WHERE (packages.account_id = 25 ) 
ActiveRecord::StatementInvalid: Mysql::Error: Unknown column 'packages.account_id' in 'where clause': SELECT `packages`.* FROM `packages`    WHERE (packages.account_id = 25 ) 
 from /Users/camwest/Sites/yardstickapp/vendor/rails/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb:212:in `log'
 from /Users/camwest/Sites/yardstickapp/vendor/rails/activerecord/lib/active_record/connection_adapters/mysql_adapter.rb:320:in `execute'
 from /Users/camwest/Sites/yardstickapp/vendor/rails/activerecord/lib/active_record/connection_adapters/mysql_adapter.rb:595:in `select'
 from /Users/camwest/Sites/yardstickapp/vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb:7:in `select_all_without_query_cache'
 from /Users/camwest/Sites/yardstickapp/vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/query_cache.rb:62:in `select_all'
 from /Users/camwest/Sites/yardstickapp/vendor/rails/activerecord/lib/active_record/base.rb:661:in `find_by_sql'
 from /Users/camwest/Sites/yardstickapp/vendor/rails/activerecord/lib/active_record/base.rb:1548:in `find_every'
 from /Users/camwest/Sites/yardstickapp/vendor/rails/activerecord/lib/active_record/base.rb:615:in `find'
 from /Users/camwest/Sites/yardstickapp/vendor/rails/activerecord/lib/active_record/associations/has_many_through_association.rb:73:in `find_target'
 from /Users/camwest/Sites/yardstickapp/vendor/rails/activerecord/lib/active_record/associations/has_one_through_association.rb:23:in `find_target'
 from /Users/camwest/Sites/yardstickapp/vendor/rails/activerecord/lib/active_record/associations/association_collection.rb:353:in `load_target'
 from /Users/camwest/Sites/yardstickapp/vendor/rails/activerecord/lib/active_record/associations/association_proxy.rb:112:in `reload'
 from /Users/camwest/Sites/yardstickapp/vendor/rails/activerecord/lib/active_record/associations.rb:1219:in `package'
 from (irb):22
A: 

Looks like I found my answer by reading through the documentation:

:through

Specifies a Join Model through which to perform the query. Options for :class_name and :foreign_key are ignored, as the association uses the source reflection. You can only use a :through query through a has_one or belongs_to association on the join model.

What this tells me is that you can't use :through on has_one on anything but the Subscription model (my join model). Sucks! If anyone has any other answers that'd be great.

camwest
class Account; def package; subscription.package if subscription; end; end
klochner
+1  A: 

As of Rails 2.2.1 you can use delegate:

class Account
  delegate :package, :to => :subscription
end

http://apidock.com/rails/Module/delegate

hgimenez