控制器最佳实践:显示多种方法或多种情况

发布于 2024-11-05 22:46:07 字数 1204 浏览 1 评论 0原文

我经常构建控制器,我想要多种方法 (此外还有索引、编辑、显示等)。大多数时候我的动作 欲望可以集中到表演中,因为它们是简单的 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

所有内容都在一种方法中显示出

  • 大量的逻辑
  • DRY ? # 逻辑需要大量额外代码
  • 更少的路由

单独的方法

  • 更多的路由
  • 而不是 DRY
  • 简单的方法查找
  • 更容易阅读单个方法

因此,真正的问题是,其中哪一项技术更少 坏的。

I'm frequently building controllers where i would like multiple methods
(in addition to index, edit, show, etc.). Most of the time the actions i
desire could be lumped into show as they are simple GET operations,
however I don't want to put too much logic in any one controller action.

Here is a quick example of two different ways to achieve the same
thing...

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

Everything in show

  • a ton of logic in one method
  • DRY ? # lots of extra code needed for logic
  • Less routing

Seperate Methods

  • More routing
  • not DRY
  • Easy method lookup
  • Easier to read individual methods

So again the real question is, which one of those techniques are less
bad.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

辞取 2024-11-12 22:46:07

我会做类似的事情:

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

I would do something like:

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

This will call whatever method is passed in params[:id], as long as it's in the whitelist (to prevent arbitrary code injection).

If having separate routes was a plus to you (nicer urls?), you could also dynamically generate the methods and routes with something like this:

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

And then in routes.rb:

FOLLOW_ACTIONS.each do |action|
    match action.to_sym => "controller##{action}"
end
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文