我经常构建控制器,我想要多种方法 (除了索引,编辑,显示等)。大部分时间都是我的行动 由于它们是简单的GET操作,因此可能会被集中到展示中, 但是我不想在任何一个控制器动作中加入过多的逻辑。
以下是两种实现相同方法的快速示例 事...
class TwitterFriendController < ApplicationController
## lump everything into show?
def show
if params[:id] == "follow"
users = current_user.following
elsif params[:id] == "follow_me"
users = current_user.users_who_follow_me
elsif params[:id] == "following_follow_me"
users = current_user.following_who_follow_me
elsif params[:id] == "following_who_do_not_follow_me"
users = current_user.following_who_do_not_follow_me
...
end
respond_with do |format|
format.json do {...}
end
end
## or split everything out into separate methods, this requires
additional routing
def following
...
end
def users_who_follow_me
...
end
def following_who_follow_me
...
end
def following_who_do_not_follow_me
...
end
end
真正的问题是,这些技术中的哪一种 less 坏。
答案 0 :(得分:7)
我会做类似的事情:
FOLLOW_WHITELIST = %w[ follow follow_me following_follow_me following_who_follow_me following_who_do_not_follow_me ]
def show
if FOLLOW_WHITELIST.include? params[:id]
users = current_user.send params[:id].to_sym
end
respond_with do |format|
format.json do {...}
end
end
这将调用params [:id]中传递的任何方法,只要它在白名单中(以防止任意代码注入)。
如果拥有单独的路线对您有好处(更好的网址?),您还可以使用以下内容动态生成方法和路线:
class TwitterFriendController < ApplicationController
FOLLOW_ACTIONS = %w[ follow follow_me following_follow_me following_who_follow_me following_who_do_not_follow_me ]
FOLLOW_ACTIONS.each do |action|
define_method action do
users = current_user.send action.to_sym
respond_with do |format|
format.json do {...}
end
end
end
end
然后在routes.rb中:
FOLLOW_ACTIONS.each do |action|
match action.to_sym => "controller##{action}"
end