first, the models:
class Listing < ActiveRecord::Base
has_many :keyword_links
has_many :keywords, :through => :keyword_links, :conditions => "active
1"
end
class Keyword < ActiveRecord::Base
has_many :keyword_links
has_many :listings, :through => :keyword_links, :conditions => "active
1"
end
class KeywordLink < ActiveRecord::Base
belongs_to :keyword
belongs_to :listing
end
the problem is, when i loop through all the @listing.keywords, I get ALL
the
keyword_links instead of just the keyword_links for that listing. For
instance, if my @listing has an ID of 7, I’ll still have
keyword_listings
with 'listing_id’s of 2, 3, etc.
i notice (in the logs) when I loop through @listing.keywords and access
keyword_link, AR makes a query of
SELECT count(*) AS count_all FROM keyword_links WHERE
(keyword_links.keyword_id = 13)
obviously missing the listing_id part of the WHERE.
what am I missing to make this happen?
thank you,
ed
Looking at your models, I wonder if what you really need is
has_and_belongs_to_many.
Something like:
class Listing < ActiveRecord::Base
has_and_belongs_to_many :keywords, :join_table => “keyword_links”,
:conditions => “active = 1”
end
class Keyword < ActiveRecord::Base
has_and_belongs_to_many :listings, :join_table => :keyword_links,
:conditions => “active = 1”
end
Page 239-241 of Agile Web D. With Rails describes this.
Julian
thank you for the response. i should have given more info. the reason
I
went with :through instead of HABTM is that my keyword_links table has
data
i need to access…it’s not just a simple join table. ie:
CREATE TABLE keyword_links
(
id
int(10) unsigned NOT NULL auto_increment,
listing_id
int(10) unsigned NOT NULL default ‘0’,
keyword_id
int(10) unsigned NOT NULL default ‘0’,
active
tinyint(1) NOT NULL default ‘1’,
max_bid
decimal(6,2) NOT NULL default ‘0.00’,
url
text NOT NULL,
impressions
int(10) unsigned NOT NULL default ‘0’,
modified_on
datetime default NULL,
created_on
datetime default NULL,
PRIMARY KEY (id
)
)
i used through so i could access those columns (max_bid, impressions,
etc).
any thoughts on why it’s pulling back all the keyword_links instead of
just
that listing’s?
ed
I think what is happening is this.
@listing.keywords returns an array of the keywords associated with the
listing. If you then apply .keyword_links to each of those keywords,
ActiveRecord does just that. It returns an array of the keyword_links
associated with each keyword. Although only looking at each keyword
associated with the listing, it grabs every single keyword_link that the
keyword is linked to.
So, if at present you are doing something like:
@listing.keywords.each{|k| do_something(k.keyword_links) }
You could instead do:
@listing.keywords.each{|k| do_something(k.keyword_links.find(:all,
:conditions => [“listing_id = ?”, @listing.id]) }
This will put the listing_id condition into the WHERE.
Julian
that makes sense. and it works!
thanks a lot Julian - you rock.
ed