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_off
和 quarter_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。
如何在 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_off
和 quarter_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。