如何在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
的库中,然后在控制器中创建库类的新实例会更好吗?或者有更好的方法来实现这个目标吗?
答案 0 :(得分:2)
要问自己的问题是“这个逻辑对视图,模型或两者都有用吗?”
如果答案是它只对显示有用,我会将该逻辑放在视图帮助器中。如果它对模型也有好处,那就把它放在那里。也许是这样的:
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>
答案 1 :(得分:1)
好吧,您可以添加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
。
答案 2 :(得分:1)
首先,你有一些语法问题。定义方法时需要使用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
此外,您在控制器的formatter
方法中定义了局部变量show
。这实际上并没有做任何事情,只是将一些值分配给仅存在于该方法中的变量。只有控制器的实例变量(带有@
的变量)才能传递给视图。
话虽如此,RoR中的最佳实践是保持控制器“瘦”,这意味着只使用控制器来验证,授权,加载模型,为您查看分配实例变量,处理任何前者的错误,然后根据请求的格式呈现视图。
另一种最佳做法是不在视图中包含太多逻辑。这样,您的逻辑可以与其他视图共享和重用,而不必为您创建的每个新视图重新编写。它还使您的视图更具可读性,因为它们会像简单的列表一样阅读,而不是让人们尝试在整个地方破译嵌入式ruby。
如果代码是您的其他模型之一可以从使用中受益的东西,则将其放入模型代码中(或者如果逻辑复杂或与现有模型没有真正的内聚,则创建一个新的普通旧Ruby对象)。
如果逻辑只是为了使视图更漂亮或更好的格式,但实际上不会被模型使用,那么它应该采用某种类型的view helper或{{3 }}