Adding Methods on Associations in Rails

Many times, you may find yourself interested in moving some of your logic outside of the view and into a model, so that you can re-use it throughout your app. But sometimes, the method you may want to define needs to be on an association of two models, and not on the models themselves.

As a real world scenario, imagine you are making an online game in which two models exist, Game and Score. The Game model keeps track of when the game was started, who started it, the level of difficulty, etc. The Score model keeps track of the value of the score, the round the score was done in, and the time the score was placed. The Game model has many Score models. Obviously, when the game is over, we are going to want to be able to see the total score. But what model do we define the method on? The Game model, itself, doesn’t have any scores and a Score object only knows about itself and not all the others that belong to the parent Game object.

This is a situation where the method needs to be defined on the association of Game and Score. Anytime the value you are trying to obtain can only be calculated with a parent and a child of an association, then you need to define the method on the association.

How to define it

Turns out that defining the method is a little trivial. The has_many method, used for creating one-to-many relationships, accepts a block in which you can define methods. Inside that block, self is set to the collection of children in the relationship. So now to define your total_score method:

1
2
3
4
5
6
7
8
9
  class Game < ActiveRecord::Base
    has_many :scores do
      def total_score
          total = 0
          self.each { |score| total += score.value }
          total
      end
    end
  end

Then, in the app …

1
2
3
4
5
6
7
g = Game.create(:user_id => 1)
g.scores.build(:value=>20)
g.scores.build(:value=>40)
g.scores.build(:value=>60)
g.save
g.scores.total_score
# 120
  • Digg
  • del.icio.us
  • Facebook
  • Google Bookmarks
  • Twitter

Comment | Trackback

, ,
Code

2 Responses to “Adding Methods on Associations in Rails”

  1. Szymon PrzybyƂ Says:

    August 10th, 2013 at 5:54 pm

    Wow, that’s freakin awesome!

    I’ve read a lot of Rails tutorials, but I didn’t know that it is possible to define methods for associations :D

  2. Frank Says:

    August 13th, 2013 at 4:15 am

    Yea, it’s a super useful technique. I’m sure you’ll find a whole bunch of uses for it!

Leave a Reply