Ruby on Rails: использование вложенных named_scopes - PullRequest
2 голосов
/ 20 апреля 2010

Я только что обратился к стековому потоку от друга, который помог мне с проблемой, с которой я столкнулся. Я довольно новичок в ruby ​​on rails и работаю над совместным проектом, в котором у нас есть сценарий (medal_worker.rb), который планируется запускать через определенные промежутки времени, чтобы награждать людей различными медалями на основе различного участия и успеха на нашем сайте. Одна из новых медалей, над которыми я работаю, награждает людей за «вехи». Для решения этой проблемы, скажем, мы хотим дать им медали, когда они делают 100, 1000 и 10000 комментариев. Я хотел бы сделать это, используя named_scopes из модели User (user.rb), чтобы получить отфильтрованные списки пользователей, которых я ищу.

Мой вопрос таков: как мне найти пользователей, у которых нет соответствующих медалей для соответствующего уровня комментариев этапа (предпочтительно с использованием named_scopes из модели User)?

Вот выдержка из моего файла model_worker.rb:

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

Вот где я нахожусь с named_scopes в пользовательской модели (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] }
}

Это работает не так, как мне хотелось бы, но я не знаю, в чем проблема в named_scopes или как я передаю аргументы или что. Благодарю.

1 Ответ

1 голос
/ 20 апреля 2010

Твой named_scopes выглядит хорошо. За исключением того, что вы начинаете с одного апострофа и заканчиваете двойным апострофом в условии not_awarded_medal.

EDIT

Забери это обратно. Ваш not_awarded_medal named_scope выключен.

Попробуйте что-то вроде этого:

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
    ]
  }
}

непроверенных

Теперь предполагается, что у вас есть следующие отношения:

User: has_many :awards Award: belongs_to :user

Если вы используете has_many :through, то вам придется изменить SQL для просмотра таблицы объединения (users_awards).

Но я вижу пару вещей в функции award_comment_milestone.

Какой параметр входит в award_comment_milestone? Это массив комментариев или счетчик комментариев? Также где определяется medal?

Если comments - массив, вам нужно передать comments.length в frequent_comment_club_members. Если это счет, то я переименую его в comments_count, чтобы следующий человек мог быстрее понять логику.

Некоторые общие замечания:

  • not_awarded_medal должен принимать только medal_id, а не весь объект (не нужно выполнять несколько запросов)
  • Почему ты делаешь Medal.find_by_id(medal.id)? У вас уже есть предмет медали.
...