Problems with rspec, models and relationships in 2.0

I have a couple of problems which are kinda related, so I’ll out them
both here. I’ve been trying out rspec for the first time and I’m new
to has_many :through relationships, so excuse me.

I want to relate a User to a WorldCity through a Locations
relationship.

############file:models/user.rb
class User < ActiveRecord::Base
has_many :locations
has_many :world_cities, :through => :locations
end

############file:models/world_city.rb
class WorldCity < ActiveRecord::Base
has_many :locations
has_many :users, :through => :locations
end

############schema.rb
ActiveRecord::Schema.define(:version => 3) do

create_table “locations”, :force => true do |t|
t.integer “user_id”
t.integer “world_city_id”
t.datetime “created_at”
t.datetime “updated_at”
end

create_table “users”, :force => true do |t|
t.string “username”
t.string “name”
t.integer “location_id”
t.datetime “created_at”
t.datetime “updated_at”
end

create_table “world_cities”, :force => true do |t|
t.string “name”
t.float “latitude”
t.float “longitude”
t.string “country”
t.string “region”
t.integer “location_id”
t.datetime “created_at”
t.datetime “updated_at”
end

end

###########user_spec.rb
describe User do
fixtures :world_cities

before(:each) do
@user = User.create( :name => “Bob Harris”, :username =>
“bobharris” )
end

it “has a user with username ‘bobharris’” do
User.find_by_username(“bobharris”).should be_valid
end

it “has a user with username ‘bobharris with a related WorldCity’”
do
#########???
end

end

Question

I want the model to be able to assign a random WorldCity to a new user
(not really important why here). Where should this be done and how do
I test it in rspec? I’m sure if I had an example I could understand
this, but can I change the user.rb to override the create method and
add a location; does the rails framework let me assign a WordCity to a
User and take care of the relationship (that would be nice).

I’ve tried everything I can think of but can’t get my head around it.

Please help.

If you’re going to use has_many :through then you also need a model
for the join table (Location). You may have that but you didn’t
describe it above.

As for assigning to that join table, there are many ways you can do it
depending on how early you need the association. Check into the
before_xxx (create, validate, etc) ActiveRecord callbacks that allow
you to hook into the object creation process without having to
override the default functionality.

On Mar 20, 8:10 am, Col W. [email protected]

On Mar 20, 12:21 pm, AndyV [email protected] wrote:

If you’re going to use has_many :through then you also need a model
for the join table (Location). You may have that but you didn’t
describe it above.

Yes I have:

class Location < ActiveRecord::Base
belongs_to :user
belongs_to :world_city
end

As for assigning to that join table, there are many ways you can do it
depending on how early you need the association. Check into the
before_xxx (create, validate, etc) ActiveRecord callbacks that allow
you to hook into the object creation process without having to
override the default functionality.

Thanks, I will.

You don’t need the location_id field in users and world_cities tables.
locations has no id field. Nor is it needed.

The user record may need to be saved before you can create a location
relationship. It has no id until it is saved

user = User.create(:name => “Fred Flintstone”, :username => “fred”)
loc = randomCity()
user.locations << loc
user.save

HTH,
Jeffrey

Quoting Col W. [email protected]:

Good catch Jeffrey. The location_id in both User and WorldCity is
unnecessary.

For the assignment, I’d work along these lines (untested):

class User < ActiveRecord::Base
has_many :locations
has_many :world_cities, :through => :locations

before_create :assign_random_city

private
def assign_random_city
self.locations.create :world_city=>WorldCity.random
end
end

On Mar 22, 10:18 am, “Jeffrey L. Taylor” [email protected]

So assuming that the random mentioned below works, does that mean that
I should be ding somethingg kime this in user.rb?

def before_create
wc = WorldCity.new.random
loc = Location.create( :world_city_id => wc.id, :user_id => @id)
@location_id = loc.id
end

Thanks all for you replies.