问题描述
我一直在 Rails 代码中看到这个:
I see this all the time in rails code:
before filter :get_post, only: [:edit, :update, :destroy]
def edit
# code .......
end
def update
# code .......
end
def destroy
# code .......
end
private
def get_post
@post = Post.find(params[:id])
end
我知道它不会将同一行代码重复三遍,但是通过将代码重构为私有方法而不隐藏实例变量,没有更容易阅读和更好的方法来完成相同的事情吗?前过滤器?
I understand it keeps from repeating the same line of code three times, but isn't there a much easier to read and better way to accomplish the same thing by just refactoring the code into a private method without hiding the instance variable and the before filter?
private
def get_post(post_id)
Post.find(post_id)
end
然后你可以在action中保留实例变量
Then you can keep the instance variable in the action
def edit
@post = get_post(params[:id])
end
在私有方法中隐藏实例变量在概念上没有意义.为什么这在 Rails 中如此普遍?
It doesn't make sense conceptually to hide instance variables in private methods. Why is this so prevalent in rails?
推荐答案
对于这个特定的实践,您可能会看到很多不同的意见.就个人而言,我同意你的看法;我觉得严格遵守 DRY 只会通过将实例变量隐藏在文件底部的方法中来引入一些混乱.我什至不确定 get_post
方法是否真的让你自己买.也就是说,在许多情况下,我更喜欢明确(如果这是一个词)而不是简洁,对于在每个控制器中始终使用此技巧的团队来说,可能不会有那么多(如果有的话)混淆.
You'll probably see a lot of differing opinions on this particular practice. Personally, I agree with you; I feel that the strict adherence to DRY only serves to introduce a bit of confusion by hiding away the instance variable in a method down at the bottom of the file. I'm not even sure a get_post
method really buys you very much myself. That said, I tend to prefer explicicity (if that's a word) over terseness in many cases, and for a team that uses this trick consistently in every controller, there may not be as much (if any) confusion.
如果过滤器封装的复杂一点,可能值得.例如,流行的授权库 CanCan by Ryan Bates 引入了一个名为 load_and_authorize_resource 的控制器类宏code> 安装
before_filter
以便自动加载 RESTful 资源并授权当前用户访问.每个方法这可能超过一两行,并且不会每次都逐字重复.
If the filter encapsulates a little more complexity, it may be worth it. For example, the popular authorization library CanCan by Ryan Bates introduces a controller class macro called load_and_authorize_resource
that installes before_filter
s such that RESTful resources are automatically loaded and authorized for access against the current user. This could potentially be more than a line or two per method, and would not repeated verbatim each time.
一些 Rails 开发人员使用了一个流行的中间立场,即将 before_filter
指定为一个块,因此您不必重复自己,但实例变量位于文件顶部:
There's a popular middle-ground that some Rails devs use, which is to specify the before_filter
as a block, so you don't have to repeat yourself, but the instance variable is up at the top of the file:
before_filter(only: [:edit, :update, :destroy]) do
@post = Post.find(params[:id])
end
正如评论中提到的,有一些宝石,例如 decent_exposure,有助于使这种模式正式化,并且使其显着减少隐藏"或混淆(因为它已明确声明且 API 已知).
As mentioned in the comments, there are some gems, like decent_exposure, which help formalize this pattern and make it significantly less "hidden" or confusing (since it's declared explicitly and the API is known).
这篇关于在过滤器中隐藏实例变量是不是很糟糕?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!