Ruby on Rails:从方法中获取 return 数据的正确方法

Ruby on Rails: proper way to return data from methods

如何在 RoR 控制器中遵循 OOP 标准?

设置:将数据提交到表单,然后对其进行处理以进行显示。这是一个简化的例子。

app/controllers/discounts_controller.rb  
...  
def show  
  @discount = Discount.find(params[:id])  
  formatted = calc_discounts(@discount)  
end  
...  

private  
  calc_discounts    
    half_off = @discount.orig_price * .5  
    quarter_off = @discount.orig_price * .25  
    return {:half => half_off, :quarter => quarter_off}  
  end  
...  

还是将它放在带有 attr_accessor 的库中,然后在控制器中创建库的新实例 class 更好?还是有更好的方法来实现这一点?

问自己的问题是"is this logic useful for the view, model, or both?"

如果答案是它仅用于显示目的,我会将该逻辑放在视图助手中。如果它对模型也有好处,就把它放在那里。也许是这样的:

class Discount
  def options
    {half: (self.orig_price * .5), quarter: (self.orig_price * .25)}   
  end
end

然后在您的控制器中,您可以找到有问题的记录:

def show  
  @discount = Discount.find(params[:id])  
end  

并在视图中显示:

<h1>half: <%= @discount.options[:half] %> </h1>
<h1>quarter: <%= @discount.options[:quarter] %> </h1>

嗯,您可以将 half_offquarter_off 作为方法添加到您的模型中:

class Discount < ActiveRecord::Base
  def half_off
    orig_price * 0.5
  end

  def quarter_off
    orig_price * 0.25
  end
end

.. 然后执行以下操作:

def show
  @discount = Discount.find(params[:id])
end

现在您可以在您的视图中调用 @discount.half_off@discount.quarter_off..

首先,您遇到了一些语法问题。当您定义方法时,您需要使用 def 关键字,并且自 Ruby 1.9 以来,您可以在定义避免 hashrockets 的哈希时使用快捷方式,因此它是:

def calc_discounts
    half_off = @discount.orig_price * .5  
    quarter_off = @discount.orig_price * .25  
    return {half: half_off, quarter: quarter_off}  
end  

此外,您在控制器的 show 方法中定义了一个局部变量 formatter。这实际上并没有做任何事情,只是将一些值分配给仅存在于该方法中的变量。只能将控制器的实例变量(带有@的变量)传递给视图。

也就是说,RoR 中的最佳实践是保留控制器 "skinny",这意味着仅使用控制器来验证、授权、加载模型、分配实例变量供您查看、处理任何错误前者,然后根据请求的格式渲染视图。

另一个最佳做法是不要在您的视图中包含太多逻辑。这样,您的逻辑可以与其他视图共享并被其他视图重用,而不必为您创建的每个新视图重新编写。它还使您的视图更具可读性,因为它们读起来就像要显示的内容的简单列表,而不是让人们试图破译到处都是嵌入的 ruby。

如果代码是您的其他模型之一可以从能够使用中受益的东西,请将其放入您的模型代码中(或者创建一个新的普通旧 Ruby 对象,如果逻辑是否复杂与现有模型真正结合)。

如果逻辑只是为了使视图更漂亮或格式更好,但实际上不会被模型使用,那么它应该采用某种类型的 view helper or decorator