2013-10-23 63 views
1

我是相当新的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

'@my_grades = Widget.include(:等级)。凡(等级:{USER_ID:SITE_ID})。限制(20)'也许? – MrYoshiji

+1

除了@ MrYoshiji的答案,尝试你的代码移到范围中的Widget模式,尊重瘦控制器,脂肪模型在轨:) – sameera207

+0

我已经做了一点挖掘,我认为正确的方式去是一个“关联延伸”上的成绩对象。我已经有了一个成绩列表,我只是想添加一些功能到列表中,但不是真的给我的Widget模型本身。 –

回答

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)