在Ruby on Rails中扩展模型

时间:2013-10-23 22:24:40

标签: ruby-on-rails

我对Ruby和Rails都很陌生,选择了一个副项目并制定了最佳实践。我想知道这个问题的推荐方法是什么。

我有一系列小部件,用户提供相关等级。在视图中显示小部件列表时,我想要显示登录用户给出的等级(如果有)。

我的工作看起来像这样,但感觉很脏。在我的控制器中,我获取了一些小部件和相关的等级(在其他地方使用的所有等级),并从该数据生成myGrades哈希:

@widgets = Widget.include(:grades).limit(20)
@myGrades = Hash[@widgets.collect{ |w| [w.id,w.grades.select{ |g| g.user_id==site_user.id}].delete_if{|k,v|v.nil?}]

在我的haml视图中,在呈现小部件时,我有类似这样的内容:

-if @myGrades.has_key?(widget.id) 
  .mygrade @myGrades[widget.id].value

但是,我觉得用“评分这个?”等方法会更好。并且在我的评分小部件上“给我 MY 等级”,没有myGrades中间人。 但最终,许多不同的对象将被评分,那么我应该如何在Rails中最好地实现这些方法,以便它们可以应用于任何评分模型?

1 个答案:

答案 0 :(得分:1)

您可以执行以下操作:

@my_grades = Widget.include(:grades).where(grades: {user_id: site_id}).limit(20)

正如@ sameera207指出的那样,你应该在你的模型中移动这个复杂的查询:创建一个范围。

class Widget < ActiveRecord::Base

  scope :for_user, lambda do |user, limit = 20| 
    includes(:grades).where(grades: {user_id: user.try(:id) || user}).limit(limit)
  end

并像这样使用它:

Widget.for_user(user_id)
# works also with a user object:
Widget.for_user(user)
# or if you want a custom limit:
Widget.for_user(user_id, 50)