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.

+2


a source to share


1 answer


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.
+1


a source







All Articles