help updating cross-reference table

I am trying to update a cross-reference table in a database when the user submits a simple form. The table has three columns, 'id', 'location_id' and 'user_id'.

Using this action, I get no errors, but nothing happens to the table:

    def update       @user = User.find(params[:id])       @locations = Location.find(:all)       @locationsusers = LocationsUser.find(params[:id])       if @locationsusers.update_attributes(:user_id => @user, :location_id => @locations)         flash[:notice] = 'Data was successfully updated.'         redirect_to :action => 'list'       else         render :action => 'edit'       end     end

If I try to substitute the update_attributes line with:

   if @locationsusers.update_attributes(params[:id])

I see the error, "undefined method `stringify_keys!' for "3":String".

If I try to do this:

   @locationsusers = LocationsUser.find(:all)    if @locationsusers.update_attributes(params[:id])

I see the error, "NoMethodError in UserController#updateLocation undefined method `update_attributes'"

How can I do this correctly?

Quoting Mr. Bill <rails-mailing-list@andreas-s.net>:

I am trying to update a cross-reference table in a database when the user submits a simple form. The table has three columns, 'id', 'location_id' and 'user_id'.

Using this action, I get no errors, but nothing happens to the table:

    def update       @user = User.find(params[:id])       @locations = Location.find(:all)       @locationsusers = LocationsUser.find(params[:id])       if @locationsusers.update_attributes(:user_id => @user, :location_id => @locations)

Try:   if @locationusers.update_attributes(:user_id => @user.id,

However, since @locations is an array of Location(s), this code probably isn't what you want at all. You could do:

  if @locationusers.update_attributes(:user_id => @user.id,      :location_id => @locations.map(&:id)

But what you probably want is a :has_many :through association table. Off the top of my head:

Class LocationUsers < ActiveRecord::Base   belongs_to :user   belongs_to :location end

Class Users < ActiveRecord::Base   has_many :location_users   has_many :locations, :through => :location_users end

Class Locations < ActiveRecord::Base   has_many :location_users   has_many :users, :through => :location_users end

def update   @user = User.find(params[:id])   @locations = Location.find(:all)   @locations.each {|l| @user.locations << l} end

HTH,   Jeffrey

Quoting Jeffrey L. Taylor <ror@austinblues.dyndns.org>:

Quoting Mr. Bill <rails-mailing-list@andreas-s.net>: > > I am trying to update a cross-reference table in a database when the > user submits a simple form. The table has three columns, 'id', > 'location_id' and 'user_id'. > > Using this action, I get no errors, but nothing happens to the table: > > def update > @user = User.find(params[:id]) > @locations = Location.find(:all) > @locationsusers = LocationsUser.find(params[:id]) > if @locationsusers.update_attributes(:user_id => @user, > :location_id => @locations)

Try:   if @locationusers.update_attributes(:user_id => @user.id,

However, since @locations is an array of Location(s), this code probably isn't what you want at all. You could do:

  if @locationusers.update_attributes(:user_id => @user.id,      :location_id => @locations.map(&:id)

But what you probably want is a :has_many :through association table. Off the top of my head:

[snip] If there will never be any values in the cross-reference (AKA join) table, i.e., just the three columns mentioned, the conceptually simpler has_and_belongs_to_many relationship works. IIRC, the join table should be named LocationsUsers. There is a way to override the join table name, perhaps through:

Class User < ActiveRecord::Base   has_and_belongs_to_many :locations, :through => :location_users end

Class Location < ActiveRecord::Base   has_many :location_users   has_many :users, :through => :location_users end

The update code is the same. Oh, and the class names in the previous example should be singular.

HTH,   Jeffrey

Thank you for your assistance Jeffrey. Your comments have helped.

When I try to do: def update   @user = User.find(params[:id])   @locations = Location.find(:all)   @locations.each {|l| @user.locations << l} end

I see this error: "TypeError in UserController#updateLocation can't convert Location into Integer"

When I do: @locationsusers = LocationsUser.find(params[:id]) if @locationsusers.update_attributes(:user_id => @user.id, :location_id => @locations.map(&:id))

I don't see any errors, but nothing changes in the database table. Is there something else I'm missing?

Jeffrey L. Taylor wrote:

Eureka! The action below did the trick. Thank you for all your help Jeffrey. The suggestions on the models worked also.

def update     @user = User.find(params[:id])     @locations = Location.find(:all)     @locations.each do |location|       @locationsids = location.id     end     @locationsusers = LocationsUser.new     @locationsusers.user_id = @user.id     @locationsusers.location_id = @locationsids.id     if @locationsusers.update_attributes(params[:locations_users])       flash[:notice] = 'User was successfully updated.'       redirect_to :action => 'list'     else       render :action => 'edit'     end end