Hi all I have the following models: class member has_and_belongs_to_many :disc_jockeys end class disc_jockey has_and_belongs_to_many :members end The relation table is called disc_jockeys_members and has the following fields: disc_jockeys_members(disc_jockey_id, member_id, status) So far, the field status can have values like valid, invalid, locked etc., but it is not regarded yet by Rails. So I would like to integrate it with the standard methods. josh $ script/console>> m = Member.find(:first) >> m.disc_jockeys # Returns all associated disc jockeys >> m.disc_jockeys(:status => ''valid'') # Returns associated disc jockeys with the status validThe 4th line above should change the query SELECT * FROM disc_jockeys LEFT JOIN disc_jockeys_members ON disc_jockeys.id = disc_jockeys_members.disc_jockey_id WHERE (disc_jockeys_members.member_id = 25 ) to SELECT * FROM disc_jockeys LEFT JOIN disc_jockeys_members ON disc_jockeys.id = disc_jockeys_members.disc_jockey_id WHERE (disc_jockeys_members.member_id = 25 and disc_jockeys_members.status = ''valid'') Now my question: What ActiveRecord method do I have to edit to reach this goal? Thanks for help. :-) Josh -- Posted via http://www.ruby-forum.com/.
Josh, Try this: m = Member.find(:first) m.disc_jockeys.find(:all, :conditions => "disc_jockeys_members.status = ''valid''") On 1/29/06, Joshua Muheim <forum@josh.ch> wrote:> Hi all > > I have the following models: > > class member > has_and_belongs_to_many :disc_jockeys > end > > class disc_jockey > has_and_belongs_to_many :members > end > > The relation table is called disc_jockeys_members and has the following > fields: > > disc_jockeys_members(disc_jockey_id, member_id, status) > > So far, the field status can have values like valid, invalid, locked > etc., but it is not regarded yet by Rails. So I would like to integrate > it with the standard methods. > > josh $ script/console > >> m = Member.find(:first) > >> m.disc_jockeys # Returns all associated disc jockeys > >> m.disc_jockeys(:status => ''valid'') # Returns associated disc jockeys with the status valid > > The 4th line above should change the query > > SELECT * FROM disc_jockeys LEFT JOIN disc_jockeys_members ON > disc_jockeys.id = disc_jockeys_members.disc_jockey_id WHERE > (disc_jockeys_members.member_id = 25 ) > > to > > SELECT * FROM disc_jockeys LEFT JOIN disc_jockeys_members ON > disc_jockeys.id = disc_jockeys_members.disc_jockey_id WHERE > (disc_jockeys_members.member_id = 25 and disc_jockeys_members.status > ''valid'') > > Now my question: What ActiveRecord method do I have to edit to reach > this goal? > > Thanks for help. :-) > Josh > > -- > Posted via http://www.ruby-forum.com/. > _______________________________________________ > Rails mailing list > Rails@lists.rubyonrails.org > http://lists.rubyonrails.org/mailman/listinfo/rails >-- Cody Fauser http://www.codyfauser.com
Thanks really a lot! :-) -- Posted via http://www.ruby-forum.com/.
OK, so far, so good. I can access the special fields of the relationship table now like any other attribute:>> dj = m.disc_jockeys.find(:first, :conditions => "disc_jockeys_members.status = ''invalid''") # Invalid DJ >> dj.status = ''valid'' >> dj.saveThis ends in a fatal error: ActiveRecord::StaleObjectError in Djs#accept_member Attempted to update a stale object How can I change these attributes in the habtm relationship table? Thanks a lot. :-) Josh -- Posted via http://www.ruby-forum.com/.
Josh, You can''t update the attributes in the join table. You could remove the object from the collection and then re-add it with the updated status. Search the archives of the mailing list for more potential solutions, as this topic has been discussed quite a bit. On 1/29/06, Joshua Muheim <forum@josh.ch> wrote:> OK, so far, so good. I can access the special fields of the relationship > table now like any other attribute: > > >> dj = m.disc_jockeys.find(:first, :conditions => "disc_jockeys_members.status = ''invalid''") # Invalid DJ > >> dj.status = ''valid'' > >> dj.save > > This ends in a fatal error: > > ActiveRecord::StaleObjectError in Djs#accept_member > Attempted to update a stale object > > How can I change these attributes in the habtm relationship table? > > Thanks a lot. :-) > Josh > > -- > Posted via http://www.ruby-forum.com/. > _______________________________________________ > Rails mailing list > Rails@lists.rubyonrails.org > http://lists.rubyonrails.org/mailman/listinfo/rails >-- Cody Fauser http://www.codyfauser.com
Cody Fauser wrote:> You could remove > the object from the collection and then re-add it with the updated > status.Thanks for that hint; but how can I tell Rails what status it should set in the status field of the relationship table? I searched the mailing lists, but didn''t really know what terms to use... any suggestions? :-) -- Posted via http://www.ruby-forum.com/.
Great, after hours of asking stupid questions I found out that my PDF is corrupt and that it''s missing pages 241 to 252... So now I found in the paper back version of the book that there''s a push_with_attributes method that solves my problem. Thanks anyway. :-) -- Posted via http://www.ruby-forum.com/.
Josh, This page from the documentation has a lot of really good information on associations: http://api.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html Cody On 1/31/06, Joshua Muheim <forum@josh.ch> wrote:> Great, after hours of asking stupid questions I found out that my PDF is > corrupt and that it''s missing pages 241 to 252... > So now I found in the paper back version of the book that there''s a > push_with_attributes method that solves my problem. Thanks anyway. :-) > > -- > Posted via http://www.ruby-forum.com/. > _______________________________________________ > Rails mailing list > Rails@lists.rubyonrails.org > http://lists.rubyonrails.org/mailman/listinfo/rails >-- Cody Fauser http://www.codyfauser.com
Thanks. I found now the following: http://wrath.rubyonrails.org/pipermail/rails/2006-January/008369.html I have added this code to my application.rb (just for testing purposes, I will outsource it to lib later when it works), but the method is not available! josh $ script/console>> m=Member.find 1 >> dj = DiscJockey.find 1 >> m.disc_jockeys.push(dj) >> m.disc_jockeys.update_attributes(dj, :status => ''xxx'')This gives me a "NoMethodError: undefined method `update_attributes'' for DiscJockey:Class". I tried also this way: class ActiveRecord::Associations::HasAndBelongsToManyAssociation def update_attributes(record, join_attributes = {}) if record.is_a? ActiveRecord::Base record_id = record.id else record_id = record end cols, vals = [], [] join_attributes.each do | key, val | cols << key.to_s vals << val end col_string = cols.join('' = ?, '') @owner.connection().update(sanitize_sql(["UPDATE #{@join_table} SET #{col_string} = ? WHERE #{@association_class_primary_key_name} = ? AND #{@association_foreign_key} = ?", vals, @owner.id, record_id].flatten), "Update Attributes") end end But it doesn''t work... What''s wrong here? I don''t have to restart the server when I place the stuff in controller/application.rb, do I? Greets Josh -- Posted via http://www.ruby-forum.com/.
Josh, I just tried it, but I added: module ActiveRecord ### Pasted code end Then I put the code in my lib folder as "patch_habtm.rb". Then in my config/environment.rb file at the bottom put: require ''patch_habtm''. Restart WEBrick to reload the application and give it a try. I didn''t actually try updating, but the method is there: i = Item.find(:first) => #<Item:0xb73ebecc @attributes={"name"=>"hammer", "created_on"=>"2006-01-29 13:08:25", "id"=>"1", "description"=>nil, "created_at"=>"2006-01-29 13:08:25"}>>> i.locations.respond_to?("update_attributes")=> true If you get it to work you''ll probably want to create a plugin for it and then you can just drop it into your plugins folder in each of your projects. On 1/31/06, Joshua Muheim <forum@josh.ch> wrote:> Thanks. I found now the following: > > http://wrath.rubyonrails.org/pipermail/rails/2006-January/008369.html > > I have added this code to my application.rb (just for testing purposes, > I will outsource it to lib later when it works), but the method is not > available! > > josh $ script/console > >> m=Member.find 1 > >> dj = DiscJockey.find 1 > >> m.disc_jockeys.push(dj) > >> m.disc_jockeys.update_attributes(dj, :status => ''xxx'') > > This gives me a "NoMethodError: undefined method `update_attributes'' for > DiscJockey:Class". I tried also this way: > > class ActiveRecord::Associations::HasAndBelongsToManyAssociation > def update_attributes(record, join_attributes = {}) > if record.is_a? ActiveRecord::Base > record_id = record.id > else > record_id = record > end > cols, vals = [], [] > join_attributes.each do | key, val | > cols << key.to_s > vals << val > end > col_string = cols.join('' = ?, '') > @owner.connection().update(sanitize_sql(["UPDATE #{@join_table} SET > #{col_string} = ? WHERE #{@association_class_primary_key_name} = ? AND > #{@association_foreign_key} = ?", vals, @owner.id, record_id].flatten), > "Update Attributes") > end > end > > But it doesn''t work... What''s wrong here? I don''t have to restart the > server when I place the stuff in controller/application.rb, do I? > > Greets > Josh > > -- > Posted via http://www.ruby-forum.com/. > _______________________________________________ > Rails mailing list > Rails@lists.rubyonrails.org > http://lists.rubyonrails.org/mailman/listinfo/rails >-- Cody Fauser http://www.codyfauser.com