Reputation: 4462
I am building a rails site and am having trouble with the associations. Basically I have the following:
class Publication < ActiveRecord::Base
belongs_to :category
has_one :site, :through => :category
named_scope :on_site, lambda {|s| {:include => [:site], :conditions => ['sites.slug != ?', 's']}}
end
class Category
belongs_to :site
has_many :publications
end
class Site
has_many :categories
has_many :publications, :through => :categories, :foreign_key => 'category_id'
end
Publication.first.site
produces the first publication's site, site.first.publications
does as well.
The trouble is with the on_site
named scope, which produces the following error with something like Publication.on_site('s')
Mysql::Error: Unknown column 'categories.category_id' in 'on clause': SELECT
`publications`.`id` AS t0_r0, `publications`.`shoot_id` AS t0_r1,
`publications`.`category_id` AS t0_r2, `publications`.`title` AS t0_r3,
`publications`.`slug` AS t0_r4, `publications`.`publish_on` AS t0_r5,
`publications`.`created_at` AS t0_r6, `publications`.`updated_at` AS t0_r7,
`publications`.`description` AS t0_r8, `publications`.`media_base_path` AS t0_r9,
`sites`.`id` AS t1_r0, `sites`.`name` AS t1_r1, `sites`.`created_at` AS t1_r2,
`sites`.`updated_at` AS t1_r3, `sites`.`slug` AS t1_r4, `sites`.`description` AS t1_r5,
`sites`.`dhd_merch_id` AS t1_r6, `sites`.`members_area_url` AS t1_r7 FROM `publications`
LEFT OUTER JOIN `categories` ON (`publications`.`id` = `categories`.`category_id`)
LEFT OUTER JOIN `sites` ON (`sites`.`id` = `categories`.`site_id`) WHERE (sites.slug != 's')
I need that join to be publications.category_id = categories.id, any idea on what I've got wrong?
Upvotes: 2
Views: 1727
Reputation: 2007
Well, here is a problem with your current implementation:
LEFT OUTER JOIN `categories` ON (`publications`.`id` = `categories`.`category_id`)
That SQL snippet is created by this association definition in Site
:
has_many :publications, :through => :categories, :foreign_key => 'category_id'
The foreign_key
there is not correct. Rails is looking for a column in categories
called category_id
, and expects the value of that column to match some publication id. But there is no correct foreign_key
option that you can set, because the categories
table looks like it does not have references to the publications
table - it is the other way around.
I'm not sure it is possible to make ActiveRecord's has_many :through
association work through an intermediate has_many
association. But I think that you can use the nested association feature to make this work:
class Publication < ActiveRecord::Base
belongs_to :category
#has_one :site, :through => :category
named_scope :on_site, lambda {|s| {:include => { :category => :site }, :conditions => ['sites.slug != ?', s]}}
end
Another issue is that you put s
in quotes in the conditions array. It should not be in quotes.
Upvotes: 2
Reputation: 4462
Well, I found a solution using the :joins
option for the scope, if anyone's interested. I'd still like to know if it's possible without using :joins
however.
named_scope :on_site, lambda {|s| {:joins =>
['LEFT OUTER JOIN `categories` ON (`publications`.`category_id` = `categories`.`id`) ',
'LEFT OUTER JOIN `sites` ON (`sites`.`id` = `categories`.`site_id`)'],
:conditions => ['sites.slug = ?', s]}}
Upvotes: 1