如何减少对辅助方法的调用次数

时间:2014-03-18 04:46:11

标签: ruby-on-rails optimization rails-activerecord

在我看来,我需要一个User对象来显示一些不同的属性。有一个实例变量@comments正在从控制器发送。我遍历注释并通过帮助方法获取用户信息,以减少数据库调用。

这是辅助方法:

  def user(id)
    if @user.blank? == false && id == @user.id
      return @user
    else
      return @user = User.find(id)
    end
  end 

在视图中,我按如下方式显示详细信息:

<h4> <%=user(comment.user_id).name%> </h4> 
<p><%=user(comment.user_id).bio%></p> 
<p><%=user(comment.user_id).long_bio%></p> 
<p><%=user(comment.user_id).email%></p> 
<hr>
<p><%=user(comment.admin_id).bio%></p> 
<p><%=user(comment.admin_id).long_bio%></p> 
<p><%=user(comment.admin_id).email%></p> 

我被告知在视图中分配变量是不好的做法,因此我多次调用辅助方法而不是分配返回的User对象。

有更好的方法吗?

2 个答案:

答案 0 :(得分:1)

将模型传递给视图并在视图中构建模型中包含的数据的数据是完全正常的。请记住,我并不完全确定您希望页面如何工作,但您可能拥有的一个选项是使用局部视图并将其传递给用户对象。这样,您仍然可以在局部视图中只使用一个模型,而无需设置其他变量。

此外,在不知道您正在使用什么类型的数据库或者您的模型是否有任何关联的情况下,并且假设您正在进行某些输入验证,您可能不需要这种辅助方法并且可能依赖于您的ORM获取用户对象。

例如:

<%= comment.user.age %>

这不比你现在获得的效率更高,但它确实使代码看起来更清晰。

另一种选择:在视图中设置用户变量。此时您没有在视图中执行逻辑,只是将一些数据存储到堆中供以后使用。

答案 1 :(得分:1)

我认为你在这里过于复杂。

假设您有用户模型

class User < ActiveRecord::Base
    has_many :comments
end

管理模型

class Admin < User

end

评论模型

class Comment < ActiveRecord::Base
    belongs_to :user
end

现在,您只需要在users表中使用类型列,您可以执行以下操作:

Admin.all (All users with type "Admin")
User.all (Really all users including type "Admin" and all other types)

并且每个评论都可以使用

comment.user.bio 

如果它是管理员,则无关紧要。

例如,请参阅http://www.therailworld.com/posts/18-Single-Table-Inheritance-with-Rails

其他信息:要减少数据库通话(N + 1个查询),请观看http://railscasts.com/episodes/372-bullet