Ruby on Rails:使用嵌套的named_scopes

时间:2010-04-20 19:09:21

标签: ruby-on-rails nested named-scope

我刚刚在这里引用了一位朋友的stackoverflow来帮助解决我遇到的问题。我对ruby on rails很新,我正在开展一个合作项目,我们有一个脚本(medal_worker.rb),计划按固定的时间间隔运行,根据我们网站上的各种参与和成功奖励各种奖牌。我正在努力的新奖牌之一奖励人们“里程碑”。出于这个问题的目的,让我们说我们想要在他们发表100,1000和10000条评论时给他们奖牌。我想通过使用User模型中的named_scopes(user.rb)来为我提供我正在寻找的用户的过滤列表。

我的问题是:如何找到没有相应里程碑评论级别奖牌的用户(最好使用用户模型中的named_scopes)?

这是我的model_worker.rb文件中的一个exerpt:

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

以下是我在用户模型(user.rb)中使用named_scopes的地方:

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 个答案:

答案 0 :(得分:1)

你的named_scopes看起来很好。除了您从单个撇号开始,并在not_awarded_medal条件语句中以双撇号结束。

修改

把它拿回来。您的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以查看join(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)?你已经拥有了奖牌对象。