I have groups of users, the groups_users join table has some extra columns which I can access to view but not update :-( I have the following schema: CREATE TABLE `groups` ( `id` int(11) NOT NULL auto_increment, `name` varchar(100) NOT NULL default '''', `created_at` datetime NOT NULL default ''0000-00-00 00:00:00'', PRIMARY KEY (`id`) ) CREATE TABLE `groups_users` ( `group_id` int(11) NOT NULL default ''0'', `user_id` int(11) NOT NULL default ''0'', `creator` int(11) NOT NULL default ''0'', `created_at` datetime NOT NULL default ''0000-00-00 00:00:00'', `role` int(11) NOT NULL default ''0'', `banned` int(11) NOT NULL default ''0'', `locked_out` int(11) NOT NULL default ''0'' ) CREATE TABLE `users` ( `id` int(11) NOT NULL auto_increment, `user_name` varchar(20) NOT NULL default '''', `email` varchar(50) NOT NULL default '''', `created_at` datetime NOT NULL default ''0000-00-00 00:00:00'', `last_login` datetime, PRIMARY KEY (`id`) ) and I want to update the following fields in groups_users: role, banned, locked_out. My models look like this: class Group < ActiveRecord::Base has_and_belongs_to_many :users class User < ActiveRecord::Base has_and_belongs_to_many :groups attr_accessor :password attr_accessible :user_name, :full_name, :email, :password, :country, :city, :img_id, :privacy_level, :banned, :role, :locked_out The controller method that I''m calling looks like this: def ban begin @group = Group.find(params[:group_id]) if (@group.ban(params[:id])) render(:text => "#{@group.name} banning user #{params[:id].to_s}") else render(:text => "#{@group.name} failed to ban user #{params[:id].to_s}") end rescue flash[:notice] = "no group found for id #{params[:id]}" render(:text => "no group found for id #{params[:id]}") end end which in turn calls the Group''s: def ban(user_id) begin self.members.each{ |m| if(m.id.eql?(user_id.to_i)) puts m.class puts m.banned m.update_attribute(:banned, 1) savable = m.save puts m.banned puts savable return true end } return false rescue puts ''what the?'' end end From the puts in the above ban method, I can see that m.banned is changed from 0 to 1, which I want, but that it isn''t getting saved to the database. Clearly I''ve missed a step out. Any help with this would be hugely appreciated. Thanks James
James, The extra columns from the join table aren''t updated when saving the object. If you need to update the data in the join table columns then it will probably be better to further develop your domain model and not use the habtm association. You could also remove the object from the collection and then re-add it using push_with_attributes. You will probably be interested in this ticket, as well: http://dev.rubyonrails.com/ticket/2462 Cody On 11/3/05, James Knight <james.knight-iDdG91AfJZGJm3qiknfgZ9BPR1lH4CV8@public.gmane.org> wrote:> I have groups of users, the groups_users join table has some extra > columns which I can access to view but not update :-( > > I have the following schema: > > > CREATE TABLE `groups` ( > `id` int(11) NOT NULL auto_increment, > `name` varchar(100) NOT NULL default '''', > `created_at` datetime NOT NULL default ''0000-00-00 00:00:00'', > PRIMARY KEY (`id`) > ) > > CREATE TABLE `groups_users` ( > `group_id` int(11) NOT NULL default ''0'', > `user_id` int(11) NOT NULL default ''0'', > `creator` int(11) NOT NULL default ''0'', > `created_at` datetime NOT NULL default ''0000-00-00 00:00:00'', > `role` int(11) NOT NULL default ''0'', > `banned` int(11) NOT NULL default ''0'', > `locked_out` int(11) NOT NULL default ''0'' > ) > > CREATE TABLE `users` ( > `id` int(11) NOT NULL auto_increment, > `user_name` varchar(20) NOT NULL default '''', > `email` varchar(50) NOT NULL default '''', > `created_at` datetime NOT NULL default ''0000-00-00 00:00:00'', > `last_login` datetime, > PRIMARY KEY (`id`) > ) > > > > and I want to update the following fields in groups_users: role, banned, > locked_out. > > My models look like this: > > class Group < ActiveRecord::Base > has_and_belongs_to_many :users > > > class User < ActiveRecord::Base > has_and_belongs_to_many :groups > > attr_accessor :password > attr_accessible :user_name, :full_name, :email, :password, :country, > :city, :img_id, :privacy_level, :banned, :role, :locked_out > > > > > The controller method that I''m calling looks like this: > > def ban > begin > @group = Group.find(params[:group_id]) > if (@group.ban(params[:id])) > render(:text => "#{@group.name} banning user #{params[:id].to_s}") > else > render(:text => "#{@group.name} failed to ban user #{params[:id].to_s}") > end > rescue > flash[:notice] = "no group found for id #{params[:id]}" > render(:text => "no group found for id #{params[:id]}") > end > end > > which in turn calls the Group''s: > > def ban(user_id) > begin > self.members.each{ |m| > if(m.id.eql?(user_id.to_i)) > puts m.class > puts m.banned > m.update_attribute(:banned, 1) > savable = m.save > puts m.banned > puts savable > return true > end > } > return false > rescue > puts ''what the?'' > end > end > > > > From the puts in the above ban method, I can see that m.banned is > changed from 0 to 1, which I want, but that it isn''t getting saved to > the database. Clearly I''ve missed a step out. > > > > Any help with this would be hugely appreciated. > > Thanks > James > > > > > _______________________________________________ > Rails mailing list > Rails-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org > http://lists.rubyonrails.org/mailman/listinfo/rails >
Cody - I have the same situation where I would like to be able to modify the data in the additional attributes of my join table. As you have said and as it is commented on in the Rails book, it''s probably better in this case to create a new domain model that belongs_to the other 2 tables. However, I''m not sure how to get all the functionality out of this that I have in the habtm setup. Will I need to write functions for things like <collection.size>? Do I put ''id'' references to the other tables in the new table? Basically how do I set it up and how do I use it? or am I better off using the patch that you linked. thanks, -Matt On 11/4/05, Cody Fauser <codyfauser-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:> > The extra columns from the join table aren''t updated when saving the > object. If you need to update the data in the join table columns then > it will probably be better to further develop your domain model and > not use the habtm association. You could also remove the object from > the collection and then re-add it using push_with_attributes. > > You will probably be interested in this ticket, as well: > http://dev.rubyonrails.com/ticket/2462 > > > Cody > > > On 11/3/05, James Knight <james.knight-iDdG91AfJZGJm3qiknfgZ9BPR1lH4CV8@public.gmane.org> wrote: > > I have groups of users, the groups_users join table has some extra > > columns which I can access to view but not update :-( > > > > I have the following schema: > > > > > > CREATE TABLE `groups` ( > > `id` int(11) NOT NULL auto_increment, > > `name` varchar(100) NOT NULL default '''', > > `created_at` datetime NOT NULL default ''0000-00-00 00:00:00'', > > PRIMARY KEY (`id`) > > ) > > > > CREATE TABLE `groups_users` ( > > `group_id` int(11) NOT NULL default ''0'', > > `user_id` int(11) NOT NULL default ''0'', > > `creator` int(11) NOT NULL default ''0'', > > `created_at` datetime NOT NULL default ''0000-00-00 00:00:00'', > > `role` int(11) NOT NULL default ''0'', > > `banned` int(11) NOT NULL default ''0'', > > `locked_out` int(11) NOT NULL default ''0'' > > ) > > > > CREATE TABLE `users` ( > > `id` int(11) NOT NULL auto_increment, > > `user_name` varchar(20) NOT NULL default '''', > > `email` varchar(50) NOT NULL default '''', > > `created_at` datetime NOT NULL default ''0000-00-00 00:00:00'', > > `last_login` datetime, > > PRIMARY KEY (`id`) > > ) > > > > > > > > and I want to update the following fields in groups_users: role, banned, > > locked_out. > > > > My models look like this: > > > > class Group < ActiveRecord::Base > > has_and_belongs_to_many :users > > > > > > class User < ActiveRecord::Base > > has_and_belongs_to_many :groups > > > > attr_accessor :password > > attr_accessible :user_name, :full_name, :email, :password, :country, > > :city, :img_id, :privacy_level, :banned, :role, :locked_out > > > > > > > > > > The controller method that I''m calling looks like this: > > > > def ban > > begin > > @group = Group.find(params[:group_id]) > > if (@group.ban(params[:id])) > > render(:text => "#{@group.name <http://group.name/>} banning user > #{params[:id].to_s}") > > else > > render(:text => "#{@group.name <http://group.name/>} failed to ban user > #{params[:id].to_s}") > > end > > rescue > > flash[:notice] = "no group found for id #{params[:id]}" > > render(:text => "no group found for id #{params[:id]}") > > end > > end > > > > which in turn calls the Group''s: > > > > def ban(user_id) > > begin > > self.members.each{ |m| > > if(m.id.eql?(user_id.to_i)) > > puts m.class > > puts m.banned > > m.update_attribute(:banned, 1) > > savable = m.save > > puts m.banned > > puts savable > > return true > > end > > } > > return false > > rescue > > puts ''what the?'' > > end > > end > > > > > > > > From the puts in the above ban method, I can see that m.banned is > > changed from 0 to 1, which I want, but that it isn''t getting saved to > > the database. Clearly I''ve missed a step out. > > > > > > > > Any help with this would be hugely appreciated. > > > > Thanks > > James > > -- > haazmatt-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org_______________________________________________ Rails mailing list Rails-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org http://lists.rubyonrails.org/mailman/listinfo/rails