# Locational relationship?

**URL:** <https://www.ruby-forum.com/t/locational-relationship/187700>\
**Category:** Rails\
**Created:** [April 28, 2010, 1:59am UTC](https://www.ruby-forum.com/t/locational-relationship/187700 "2010-04-28T01:59:53Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![robo](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/bb73d2/32.png) [@robo](https://www.ruby-forum.com/u/robo)\
**Post date:** [April 28, 2010, 1:59am UTC](https://www.ruby-forum.com/t/locational-relationship/187700/1 "2010-04-28T01:59:53Z")

</div>

ok, I’ve got a model called Location, the idea being that i have a  
bunch of locations aligned to a grid. Each location has a pointer to  
it’s neighbors, like so

create\_table “locations”, :force =\> true do |t|  
t.string “name”  
t.text “description”  
t.integer “north”  
t.integer “northeast”  
t.integer “east”  
t.integer “southeast”  
t.integer “south”  
t.integer “southwest”  
t.integer “west”  
t.integer “northwest”  
t.integer “x”  
t.integer “y”  
t.datetime “created\_at”  
t.datetime “updated\_at”  
t.integer “map\_id”  
end

whereas all the directions (north, south, east, etc) should all be  
references to other locations.

I know this is probably an easy question, but what kind of  
relationship is this, and how would I set it up in my model? like  
this?

has\_one :location, :foreign\_key =\> :north  
has\_one :location, :foreign\_key =\> :northeast  
has\_one :location, :foreign\_key =\> :east  
has\_one :location, :foreign\_key =\> :southeast  
has\_one :location, :foreign\_key =\> :south  
has\_one :location, :foreign\_key =\> :southwest  
has\_one :location, :foreign\_key =\> :west  
has\_one :location, :foreign\_key =\> :northwest

---

<div class="post-metadata">

**Author:** ![robo](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/bb73d2/32.png) [@robo](https://www.ruby-forum.com/u/robo)\
**Post date:** [April 28, 2010, 8:20am UTC](https://www.ruby-forum.com/t/locational-relationship/187700/2 "2010-04-28T08:20:55Z")

</div>

This is a self referential association

class Location \< ActiveRecordBase  
has\_one :south, :class\_name =\> ‘Location’, :foreign\_key =\> ‘south’  
end

---

<div class="post-metadata">

**Author:** ![robo](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/bb73d2/32.png) [@robo](https://www.ruby-forum.com/u/robo)\
**Post date:** [April 28, 2010, 3:20pm UTC](https://www.ruby-forum.com/t/locational-relationship/187700/3 "2010-04-28T15:20:36Z")

</div>

robo wrote:

> ok, I’ve got a model called Location, the idea being that i have a  
> bunch of locations aligned to a grid. Each location has a pointer to  
> it’s neighbors, like so
> 
> create\_table “locations”, :force =\> true do |t|  
> t.string “name”  
> t.text “description”  
> t.integer “north”  
> t.integer “northeast”  
> t.integer “east”  
> t.integer “southeast”  
> t.integer “south”  
> t.integer “southwest”  
> t.integer “west”  
> t.integer “northwest”  
> t.integer “x”  
> t.integer “y”  
> t.datetime “created\_at”  
> t.datetime “updated\_at”  
> t.integer “map\_id”  
> end
> 
> whereas all the directions (north, south, east, etc) should all be  
> references to other locations.
> 
> I know this is probably an easy question, but what kind of  
> relationship is this, and how would I set it up in my model? like  
> this?
> 
> has\_one :location, :foreign\_key =\> :north  
> has\_one :location, :foreign\_key =\> :northeast  
> has\_one :location, :foreign\_key =\> :east  
> has\_one :location, :foreign\_key =\> :southeast  
> has\_one :location, :foreign\_key =\> :south  
> has\_one :location, :foreign\_key =\> :southwest  
> has\_one :location, :foreign\_key =\> :west  
> has\_one :location, :foreign\_key =\> :northwest

I think I would avoid this. If the grid is regular, then you should  
probably just store the X and Y coordinates in the model, then do  
something like

class Location \< AR::B  
def northeast  
@northeast ||= Location.find\_by\_x\_and\_y(x + 1, y + 1)  
end  
end

## Best,

Marnen Laibow-Koser  
[http://www.marnen.org](http://www.marnen.org)  
removed\_email\_address@domain.invalid

---

<div class="post-metadata">

**Author:** ![robo](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/bb73d2/32.png) [@robo](https://www.ruby-forum.com/u/robo)\
**Post date:** [April 28, 2010, 5:01pm UTC](https://www.ruby-forum.com/t/locational-relationship/187700/4 "2010-04-28T17:01:23Z")

</div>

Is there a reason why you would avoid setting up an association for  
each one? It seems like it’s basically the exact same thing you  
proposed, but a little more long-winded. No offense meant 🙂

I mean what difference does it make if I create an association that  
finds its neighbors vs. writing a method that ends up finding the  
neighbors manually?
