# Problems with rspec, models and relationships in 2.0

**URL:** <https://www.ruby-forum.com/t/problems-with-rspec-models-and-relationships-in-2-0/132465>\
**Category:** Rails\
**Created:** [March 20, 2008, 1:11pm UTC](https://www.ruby-forum.com/t/problems-with-rspec-models-and-relationships-in-2-0/132465 "2008-03-20T13:11:04Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![Col\_W](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/dec6dc/32.png) [@Col\_W](https://www.ruby-forum.com/u/Col_W)\
**Post date:** [March 20, 2008, 1:11pm UTC](https://www.ruby-forum.com/t/problems-with-rspec-models-and-relationships-in-2-0/132465/1 "2008-03-20T13:11:04Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![Col\_W](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/dec6dc/32.png) [@Col\_W](https://www.ruby-forum.com/u/Col_W)\
**Post date:** [March 20, 2008, 1:22pm UTC](https://www.ruby-forum.com/t/problems-with-rspec-models-and-relationships-in-2-0/132465/2 "2008-03-20T13:22:52Z")

</div>

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. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)

---

<div class="post-metadata">

**Author:** ![Col\_W](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/dec6dc/32.png) [@Col\_W](https://www.ruby-forum.com/u/Col_W)\
**Post date:** [March 20, 2008, 1:38pm UTC](https://www.ruby-forum.com/t/problems-with-rspec-models-and-relationships-in-2-0/132465/3 "2008-03-20T13:38:49Z")

</div>

On Mar 20, 12:21 pm, AndyV [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) 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.

---

<div class="post-metadata">

**Author:** ![Col\_W](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/dec6dc/32.png) [@Col\_W](https://www.ruby-forum.com/u/Col_W)\
**Post date:** [March 22, 2008, 3:19pm UTC](https://www.ruby-forum.com/t/problems-with-rspec-models-and-relationships-in-2-0/132465/4 "2008-03-22T15:19:06Z")

</div>

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. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid):

---

<div class="post-metadata">

**Author:** ![Col\_W](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/dec6dc/32.png) [@Col\_W](https://www.ruby-forum.com/u/Col_W)\
**Post date:** [March 24, 2008, 3:01pm UTC](https://www.ruby-forum.com/t/problems-with-rspec-models-and-relationships-in-2-0/132465/5 "2008-03-24T15:01:38Z")

</div>

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” [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)

---

<div class="post-metadata">

**Author:** ![Col\_W](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/dec6dc/32.png) [@Col\_W](https://www.ruby-forum.com/u/Col_W)\
**Post date:** [March 20, 2008, 2:21pm UTC](https://www.ruby-forum.com/t/problems-with-rspec-models-and-relationships-in-2-0/132465/6 "2008-03-20T14:21:01Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![Col\_W](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/dec6dc/32.png) [@Col\_W](https://www.ruby-forum.com/u/Col_W)\
**Post date:** [March 31, 2008, 9:33am UTC](https://www.ruby-forum.com/t/problems-with-rspec-models-and-relationships-in-2-0/132465/7 "2008-03-31T09:33:19Z")

</div>

Thanks all for you replies.
