# Design question and opinions

**URL:** <https://www.ruby-forum.com/t/design-question-and-opinions/181633>\
**Category:** Rails\
**Created:** [January 15, 2010, 1:09am UTC](https://www.ruby-forum.com/t/design-question-and-opinions/181633 "2010-01-15T01:09:29Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![imnotquitejack](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/i/85e7bf/32.png) [@imnotquitejack](https://www.ruby-forum.com/u/imnotquitejack)\
**Post date:** [January 15, 2010, 1:09am UTC](https://www.ruby-forum.com/t/design-question-and-opinions/181633/1 "2010-01-15T01:09:29Z")

</div>

I’m just working through the Agile web dev book (which is great) and i’m  
at the point i’d like to put together something to test my  
understanding. Luckily I have a project that will help my gaming  
community organise games on modern warfare 2. It also doesn’t map onto  
the depot like for like which is good 🙂

The basic idea is you have a list of game modes and a list of maps.  
These lists can be added to. They can’t be removed but they can be set  
to inactive.

Now a game consists of a map and a game mode. A match consists of one or  
more games (specified by the user). The games for a particular match get  
chosen at random - the one rule being that the a map and game mode may  
only appear once in the match.

The application should allow the user to enter the number of games they  
want to play and generate a match. this match is given a short  
description (e.g. Team 1 v Team 2) and gets stored so that people  
playing the match can see what games they will be playing.

So far i’ve got the models i think i need:

- map(s)
- game\_modes(s)
- game(s)
- match(s)
- match\_game(s)

I’ve created the map, game\_model and match using scaffold as i want to  
be able to maintain them through the UI.

I’ve created game and match\_game as pure models as they are part of the  
match creation.

So far, am i on the right track based on good practice and design?

One consideration i did have was whether, based on the fact that the  
maps and game\_modes tables will always have a relatively small number of  
entries, i should just autogenerate the rows (20 in each table = 400  
rows. random generate a number between 1 and 400 and it picks the game).  
If i was to do this where would i embed the method to autopopulate the  
game table? (in the game model itself or a helper - i’m not sure on best  
practice). This could also be called if the admin decided to update the  
table with a new entry (i.e. it would create the extra matches needed).

At this stage i haven’t even thought through how the actual UI will  
build all the bits and put them together but i’m thinking this would be  
the job of my match controller which creates a match object, x game  
objects and sets the ‘games’ property of the match object before  
committing the changes to the DB and letting rails do some magic to save  
it all (i’m not looking for someone to tell me as i’d like to work it  
out but if i’m way off track here then a pointer or 2 would be  
appreciated).

Thanks for taking the time to read and i appreciate any comments or  
opinions you can offer this newbie 🙂

---

<div class="post-metadata">

**Author:** ![imnotquitejack](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/i/85e7bf/32.png) [@imnotquitejack](https://www.ruby-forum.com/u/imnotquitejack)\
**Post date:** [January 15, 2010, 3:44pm UTC](https://www.ruby-forum.com/t/design-question-and-opinions/181633/2 "2010-01-15T15:44:14Z")

</div>

ooh found ‘has\_many\_and\_belongs\_to’ in ActiveRecord that takes care of  
the match-\>match\_game\<-game relationship nicely!

The solution i think i’m going to go with is to pre-load the game table  
and add some methods to the game model to return a game or games in the  
various ways i’ll need them e.g.

get\_random\_game  
get\_random\_active\_game(exclude\_these\_games[])  
get\_all\_active\_games

My match controller can then use these as part of the logic that builds  
the match before committing it to the db.

If someone updates the maps or game\_modes models then i’ll trigger an  
‘update\_list\_of\_games’ on the Game class to populate any new game modes  
as a result of the change.

Not sure what people feel about this but it seemed right in my head lol.

---

<div class="post-metadata">

**Author:** ![imnotquitejack](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/i/85e7bf/32.png) [@imnotquitejack](https://www.ruby-forum.com/u/imnotquitejack)\
**Post date:** [January 15, 2010, 3:57pm UTC](https://www.ruby-forum.com/t/design-question-and-opinions/181633/3 "2010-01-15T15:57:49Z")

</div>

2010/1/15 Jon C. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid):

> ooh found ‘has\_many\_and\_belongs\_to’ in ActiveRecord that takes care of  
> the match-\>match\_game\<-game relationship nicely!

The convention is for the HABTM table name to be alpha ordered and  
plural, so in this case it would be games\_matches. Then you will not  
have to explicitly name it using :through.

If you have not seen it already you may find the ActiveRecord  
Associations guide at [http://guides.rubyonrails.org/](http://guides.rubyonrails.org/) useful. Also the  
other guides there of course.

Colin

---

<div class="post-metadata">

**Author:** ![imnotquitejack](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/i/85e7bf/32.png) [@imnotquitejack](https://www.ruby-forum.com/u/imnotquitejack)\
**Post date:** [January 15, 2010, 3:53pm UTC](https://www.ruby-forum.com/t/design-question-and-opinions/181633/4 "2010-01-15T15:53:36Z")

</div>

Jon C. wrote:

> I’ve created the map, game\_model and match using scaffold as i want to  
> be able to maintain them through the UI.
> 
> I’ve created game and match\_game as pure models as they are part of the  
> match creation.
> 
> So far, am i on the right track based on good practice and design?

If you have written your Cucumber stories and/or RSpec examples before  
all this work, using them to drive your design, then you are on the  
right track to good practice and design.

> One consideration i did have was whether, based on the fact that the  
> maps and game\_modes tables will always have a relatively small number of  
> entries, i should just autogenerate the rows (20 in each table = 400  
> rows. random generate a number between 1 and 400 and it picks the game).  
> If i was to do this where would i embed the method to autopopulate the  
> game table? (in the game model itself or a helper - i’m not sure on best  
> practice). This could also be called if the admin decided to update the  
> table with a new entry (i.e. it would create the extra matches needed).

The latest version of Rails has a convention for this, and an associated  
rake task. The feature is called “Seeds.” You’ll notice there will be a  
db/seeds.rb file for putting your Ruby code to populate your seed data.  
Then you can run rake db:seed after running rake db:migrate to execute  
the data seeds.

> At this stage i haven’t even thought through how the actual UI will  
> build all the bits and put them together but i’m thinking this would be  
> the job of my match controller which creates a match object, x game  
> objects and sets the ‘games’ property of the match object before  
> committing the changes to the DB and letting rails do some magic to save  
> it all (i’m not looking for someone to tell me as i’d like to work it  
> out but if i’m way off track here then a pointer or 2 would be  
> appreciated).

I would think that the controller would simply handled the request to  
“create” a new game:

## matches\_controller.rb

def create  
@match = Match.new  
@match.start  
…

# Stuff to handle return the response

end

## match.rb

class Match \<\< ActiveRecord::Base  
…  
def start  
# Do all the stuff you need to do to start a match  
end  
…  
end

This is often referred to as “skinny controller, fat model design,” and  
is typically promoted in Rails as a “best practice.”

---

<div class="post-metadata">

**Author:** ![imnotquitejack](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/i/85e7bf/32.png) [@imnotquitejack](https://www.ruby-forum.com/u/imnotquitejack)\
**Post date:** [January 15, 2010, 4:34pm UTC](https://www.ruby-forum.com/t/design-question-and-opinions/181633/5 "2010-01-15T16:34:33Z")

</div>

Robert W. wrote:

> Jon C. wrote:
> 
> > ooh found ‘has\_many\_and\_belongs\_to’ in ActiveRecord that takes care of  
> > the match-\>match\_game\<-game relationship nicely!
> 
> The current trend in Rails is toward has\_many :through instead of  
> has\_and\_belongs\_to\_many (HABTM).

Says who? I tend to start with HABTM and refactor to has\_many :through  
if necessary.

> The has\_many :trough is more flexible,  
> and often more RESTful.

More flexible, yes. But it’s not the Simplest Thing That Could Possibly  
Work [TM] in this case.

HABTM is a special simplified case. If your data fits the special case,  
it makes sense to take advantage of it.

As for REST, that’s a routing issue, not an associations issue.

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

---

<div class="post-metadata">

**Author:** ![imnotquitejack](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/i/85e7bf/32.png) [@imnotquitejack](https://www.ruby-forum.com/u/imnotquitejack)\
**Post date:** [January 15, 2010, 4:18pm UTC](https://www.ruby-forum.com/t/design-question-and-opinions/181633/6 "2010-01-15T16:18:20Z")

</div>

Jon C. wrote:

> ooh found ‘has\_many\_and\_belongs\_to’ in ActiveRecord that takes care of  
> the match-\>match\_game\<-game relationship nicely!

The current trend in Rails is toward has\_many :through instead of  
has\_and\_belongs\_to\_many (HABTM). The has\_many :trough is more flexible,  
and often more RESTful.

Imagine what happens if you need to store something that relates to a  
particular game of a match. You can’t store that in either the matches  
nor the games tables. You would instead need access to the joining table  
match\_games.

class Match \<\< ActiveRecord::Base  
has\_many :match\_games  
has\_many :games, :through =\> :match\_games  
end

class Game \<\< ActiveRecord::Base  
has\_many :match\_games  
has\_many :matches, :though =\> :match\_games  
end

class MatchGame \<\< ActiveRecord::Base  
belongs\_to :match  
belongs\_to :game  
end

Again write your stories and use them to drive your design. This is  
opposed to trying to build your application from the perspective of the  
data model. Letting your acceptance criteria drive your design will  
develop into a better user experience. You’ll be concentrating on what  
the user sees, and how they interact with your application. I think  
you’ll find that the model almost takes care of itself as you write code  
to make your stories (and specs) pass.

Feature: player starts a new match  
As a player  
I want to start a new match  
So that I can have fun fragging my friends

Scenario: starting a match  
Given a new match  
When I start the match  
Then I should \<fill in what you expect to see (or happen)\>  
And I should

Scenario:   
Given …  
When …  
Then …

---

<div class="post-metadata">

**Author:** ![imnotquitejack](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/i/85e7bf/32.png) [@imnotquitejack](https://www.ruby-forum.com/u/imnotquitejack)\
**Post date:** [January 15, 2010, 4:45pm UTC](https://www.ruby-forum.com/t/design-question-and-opinions/181633/7 "2010-01-15T16:45:38Z")

</div>

Marnen Laibow-Koser wrote:

> Robert W. wrote:
> 
> > Jon C. wrote:
> > 
> > > ooh found ‘has\_many\_and\_belongs\_to’ in ActiveRecord that takes care of  
> > > the match-\>match\_game\<-game relationship nicely!
> > 
> > The current trend in Rails is toward has\_many :through instead of  
> > has\_and\_belongs\_to\_many (HABTM).
> 
> Says who? I tend to start with HABTM and refactor to has\_many :through  
> if necessary.

Says, DHH in his initial promotion of the decision to move to a RESTful  
design. I did not, however, say that that this was right, just that it  
has been proposed by the person who developed the idea.

> > The has\_many :trough is more flexible,  
> > and often more RESTful.
> 
> More flexible, yes. But it’s not the Simplest Thing That Could Possibly  
> Work [TM] in this case.

I concede this point.

> HABTM is a special simplified case. If your data fits the special case,  
> it makes sense to take advantage of it.
> 
> As for REST, that’s a routing issue, not an associations issue.

Again I concede. But, this was just a misuse of the terminology. I meant  
to say that having the joining model can lead to more RESTful routes in  
many cases. Again this was another point in DHH’s initial talk on the  
move to REST. At that time, however, all this REST stuff was  
experimental. I’m sure we’ve learned a lot since that initial  
presentation on the subject matter.

---

<div class="post-metadata">

**Author:** ![imnotquitejack](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/i/85e7bf/32.png) [@imnotquitejack](https://www.ruby-forum.com/u/imnotquitejack)\
**Post date:** [January 15, 2010, 4:59pm UTC](https://www.ruby-forum.com/t/design-question-and-opinions/181633/8 "2010-01-15T16:59:30Z")

</div>

Robert W. wrote:

> If you have written your Cucumber stories and/or RSpec examples before  
> all this work, using them to drive your design, then you are on the  
> right track to good practice and design.

Thats great advice and was on my list of ‘when i’ve got the basics down  
i need to go and learn about…’ list. Sounds like I should probably  
make it a priority. the later examples you gavce helped reinforce this  
for me.

> The current trend in Rails is toward has\_many :through instead of  
> has\_and\_belongs\_to\_many (HABTM). The has\_many :trough is more flexible,  
> and often more RESTful.

I did pick up on this during some reading i did this morning (Colin’s  
suggestion to read the ActiveRecord Associations guide helped me better  
understand). As this is a very simple system that i have no plans to  
extend (famous last words hehe) i felt HABTM fitted the bill.

> The latest version of Rails has a convention for this, and an associated  
> rake task. The feature is called “Seeds.” You’ll notice there will be a  
> db/seeds.rb file for putting your Ruby code to populate your seed data.  
> Then you can run rake db:seed after running rake db:migrate to execute  
> the data seeds.

Brilliant! Thank you for the pointer.

> This is often referred to as “skinny controller, fat model design,” and  
> is typically promoted in Rails as a “best practice.”

aha (penny starting to drop here)

Thanks for taking the time to read this and i really appreciate all the  
responses and advice.
