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 Jeffrey L. Taylor [email protected]:

  @user = User.find(params[:id])

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

Quoting Mr. Bill [email protected]:

  @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

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:

Quoting Jeffrey L. Taylor [email protected]:

  @user = User.find(params[:id])

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

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