views:

55

answers:

2

OK So I've got my models like so:

Team
  has_many :users, :through => memberships

User
  has_one :user_status

Now in my Team model I want to be able to find the maximum 'updated_at' value of my 'user_status' models.

I tried doing something like:

Team
  has_many :users, :through => :memberships
  has_many :user_statuses, :through => :users

  def max_last_updated_status
    user_statuses.maximum(:updated_at)
  end

but that gave me:

Invalid source reflection macro :has_one for has_many :user_statuses, :through => :users.  Use :source to specify...

So I was wondering if there's a better way of doing this, can I just create a property of the User model like:

def status_updated_at
  user_status.updated_at
end

and then change my Team class to have:

  def max_last_updated_status
    user.maximum(:status_updated_at)
  end

? I'm assuming not as 'status_updated_at' is not really a column and so the sql generation would fail...

Another perspective on this problem would be much appreciated.

+3  A: 

I would do it this way:

Team

has_many :users, :through => memberships

def max_last_updated_status
  users.map{|user| user.user_status.updated_at}.max
end

User

has_one :user_status

The method max_last_updated_status should return the max updated_at of the users in the team.

SamChandra
I like this answer, it's just the change in perspective I needed. Moving away from thinking SQL and start thinking Ruby. I've implemented it like this. Thanks a lot.
neiled
+1  A: 

In your original approach, have you tried this:

team.users.maximum "user_statuses.updated_at", :include => :user_status
# OR
team.users.maximum "`user_statuses`.updated_at", :include => :user_status

I tried with following classes and it works just fine:

class User < ActiveRecord::Base
  has_one :user_status
  has_many :memberships
  has_many :teams, :through => :memberships
end


class UserStatus < ActiveRecord::Base
  belongs_to :user
end


class Team < ActiveRecord::Base
  has_many :users, :through => :memberships
  has_many :memberships
end


class Membership < ActiveRecord::Base
  belongs_to :team
  belongs_to :user
end
Swanand
Oh I didn't realise you could do that, but of course it makes sense when you add the include, I can see how the SQL gets generated. Thanks a lot!
neiled