Ruby on Rails: using nested named_scopes
I just got a link on stackoverflow from a friend here to help with the problem I'm having. I am new to rubies on rails and I am working on a joint project where we have a script (medal_worker.rb) that is scheduled to run at regular intervals to award people with different medals based on different participation and success on our Website ... One of the new medals I'm working on rewards people for "milestones." For this problem, let's say we want to give them medals when they make 100, 1000 and 10,000 comments. I would like to do this using named_scopes from the User model (user.rb) to give me the filtered lists of the users I am looking for.
My question is, how do I find users who don't have matching medals for their respective comment level (for example using named_scopes from the User model)?
Here is an excerpt from my model_worker.rb file:
def award_comment_milestone(comments)
users = Users.frequent_comment_club_members(comments).not_awarded_medal(Medal.find_by_id(medal.id))
for user in users do
award_medal(medal, nil, user) if @award
end
end
Here I am named named_scopes in the user model (user.rb):
named_scope :frequent_comment_club_members, lambda { |*args|
{:include => comment_records, :conditions => ['comment_records.comment_type = ? and comment_records.comments >= ?', 'User', (args.first || 0)]}
}
named_scope :not_awarded_medal, lambda { |medal|
{:include => :awards, :conditions => ['awards.medal_id not in (select awards.medal_id from awards where awards.medal_id = ?)", medal.id] }
}
It doesn't work as I would like, but I don't know if there is a problem with named_scopes or how I am going through the controversy or what. Thank you.
a source to share
Yours named_scopes
looks great. Except that you start with a single apostrophe and end with a double apostrophe in a condition expression not_awarded_medal
.
EDIT
Take it back. Your not_awarded_medal
named_scope is disabled.
Try something like this:
named_scope :not_awarded_medal, lambda { |medal_id|
{ :include => :awards,
:conditions => [
"? not in (select awards.id from awards where awards.user_id = users.id)", medal_id
]
}
}
unverified
This now assumes that you have the following relationship:
User: has_many :awards
Award: belongs_to :user
If you are using has_many :through
you will have to modify the SQL to look at the join (users_awards) table.
-
But I see several things in the function award_comment_milestone
.
What parameter is included in award_comment_milestone
? Is it an array of comments or is it the number of comments? Also where is it medal
defined?
If comments
is an array, you need to pass comments.length
to frequent_comment_club_members
. If this is an account, I would rename it to comments_count
so the next person can understand the logic faster.
Some general observations:
-
not_awarded_medal
should just take medal_id and not the whole object (no need to make multiple requests) - Why are you doing
Medal.find_by_id(medal.id)
? You already have a medal object.
a source to share