我正在阅读一篇关于Rails控制器的文章,你能帮我理解下面这句话的含义: “最好的控制器是Dilbert-esque:它在不知道(或关心)如何完成的情况下发出命令。”
在您看来,这是真的吗?
例如,如果我正在访问与主题控制器关联的索引页面,我将严格定义subject_controller.rb中的索引方法,因此我对文章中的含义感到困惑,因为我会以为相反。
请指点什么? 谢谢,对不起,如果这太可解释了。这是原始文章:http://betterexplained.com/articles/intermediate-rails-understanding-models-views-and-controllers/
答案 0 :(得分:2)
本文讨论的是MVC架构。从这样的文章中拿走的重要之处在于Rails最好用Fat Models和Thin Controller编写。这意味着您希望在模型中拥有大量的方法/函数,并希望从控制器中调用函数。索引是一个不好的例子,因为通常你不会在那里进行很多事情。
您的索引控制器通常看起来像这样
def index
@subjects = Subject.all
end
如果您想要显示您的主题的范围顺序,您可以在模型中使用块执行此操作,如下所示:
default_scope { order("id DESC") }
一个不那么做作的例子可能看起来像这样:例如,假设您有一个接受输入的应用程序,接受该输入并根据用户输入的内容计算多个计数器。您的控制器可能名为subject_tally,如下所示:
def subject_tally
@subject = Subject.find(params[:id])
@subject.winnings += 1
@subject.total_matches += 1
@subject.win_percentage = @subject.winnings.to_f/@subject.total_matches
redirect_to subjects_path
end
这是错误的。这是一个非常胖的控制器,很容易移动到应该
的模型。如果写得恰当,它看起来像这样:
subjects_controller.rb :(控制器)
def subject_tally
@subject = Subject.find(params[:id])
@subject.subject_tally
redirect_to subjects_path
end
subject.rb :(模特)
def subject_tally
self.winnings += 1
self.total_matches += 1
self.win_percentage =winnings.to_f/total_matches
end
正如您所看到的,您只能从控制器拨打一个电话,而且它并不关心"在后端实际发生了什么。它确实在那里传递一个值(在这种情况下,是相关主题的ID)并引导你到另一个页面,在这种情况下,索引。
此外,如果您注意到,您不需要在模型的subject_tally函数中随处添加那个讨厌的@subject ......您只需使用它就可以引用对象的属性self.winnings
您要在其中分配属性的地方。 Ruby足够聪明,可以知道该方法适用的当前主题(因为你从控制器调用了一个主题上的那个功能),事实上,如果你只是“{1}”,你甚至不需要self.
检索属性而不是分配属性...这就是为什么我们在self
或最后一行winnings.to_f
之前不需要total_matches
。
非常方便,代码少,时间少,可以。
答案 1 :(得分:1)
最好的控制器是Dilbert-esque:它在不知情的情况下发出命令 (或关心)它是如何完成的。
意味着你应该在控制器中放置更少的逻辑, 控制器应该只知道要调用的内容以获得所需内容,并且不知道如何执行某项操作。
在rails开发者的“Sandy Metz规则”(http://robots.thoughtbot.com/sandi-metz-rules-for-developers)中,她说:
控制器只能实例化一个对象。因此,视图只能 知道一个实例变量,视图应该只发送消息 到那个对象
只有一个对象看起来有点极端,但会想到你应该在控制器中放置多少业务逻辑(没有逻辑)。