可以在视图Rails中调用ActiveRecord方法

时间:2015-12-20 02:36:37

标签: ruby-on-rails ruby ruby-on-rails-4 activerecord methods

使用Rails 4

我想知道(并且很难找到答案)如果可以直接从视图中调用ActiveRecord方法,例如:

<%= Article.where(approved: true).count %>

<%= Article.where("short_answer is NOT NULL and short_answer != ''").count %>

我意识到通常的做法是将它们存储在控制器内部的实例变量中,但由于我使用的是部分变量,我不能这样做。

这样做好吗?可以受伤吗?有没有更好的方法来解决这个问题(例如辅助方法)?谢谢!

3 个答案:

答案 0 :(得分:4)

  

这样做好吗?可以受伤吗?

这绝对没问题,但问题是你将调用另一个数据库查询 - 这是Rails应用程序中最“昂贵”的部分。

@instance_variables设置一次,可以在整个视图中使用:

#app/views/articles/show.html.erb
#Referencing @article references stored data, not a new DB query
<%= @article.title %>
<%= @article.description %>
<%= @article.created_at %>

因为以上都使用存储的@article数据,所以数据库仅在一次(在控制器中创建@article时)。

如果在视图中调用AR方法,则每次都基本上调用一个新的db调用:

#app/views/articles/show.html.erb
#Bad practice
<%= Article.select(:name).find(params[:id]) %>
<%= Article.select(:description).find(params[:id]) %>
<%= Article.select(:created_at).find(params[:id]) %>

要直接回答您的问题,如果您只计算数据库特定数据,则可以调用该数据。

IE 如果您尝试计算@articles的数量,则可以致电@articles.sizeActiveRecord: size vs count

谨慎的开发人员将确定他们在控制器中拥有哪些数据,以及他们需要从数据库中提取哪些数据...在控制器本身中完成所有数据库工作:

#app/controllers/articles_controller.rb
class ArticlesController < ApplicationController
   def index
      @articles = Article.where(approved: true) #-> could use a scope here if you wanted
   end
end

#app/views/articles/index.html.erb
<%= @articles.size %>

Nithin的答案很好但不会超出您必须确定是否需要明确调用数据库或使用已调用数据的考虑。

最后,关于使用partial,如果必须每隔时间传递数据,您可能希望使用某种条件数据来确定是否需要调用db :

#app/views/shared/_partial.html.erb
<% approved ||= Article.approved_articles.size %>
<% short    ||= Article.short_answer_presence.size %>

这将允许您根据需要设置本地,并且如果未设置则设置“默认值”。

答案 1 :(得分:1)

您总是可以使用locals在部分内部传递这些变量:

<%= render partial: "form", locals: {zone: @zone} %>

在控制器中定义实例变量总是一个很好的做法,它不会受到影响,但你最终不会在视图中执行业务逻辑。

答案 2 :(得分:1)

你应该主要做

class Article < ActiveRecord::Base
....

  scope :approved_articles, where(approved: true)
  scope :short_answer_presence, where("short_answer is NOT NULL and short_answer != ''")
end

在您的控制器方法

@approved_articles_count     = Article.approved_articles.count
@short_answer_presence_count = Article.short_answer_presence.count

并在视图中使用这些变量。

如果是偏僻的话,就像拉曼说的那样,你可以做到。

<%= render partial: "form", locals: {approved_articles_count: @approved_articles_count, short_answer_presence_count: @short_answer_presence_count} %>