【问题标题】:Rails best practice: conditional action, multiple actions, or method?Rails 最佳实践:条件动作、多动作还是方法?
【发布时间】:2011-03-06 04:19:58
【问题描述】:

我很想获得一些关于我最近一直在编写的代码的意见。

我有一个模型,photos,它有时(但不总是)属于collection。我有一个页面供用户管理收藏,他们可以将任何未分​​配的照片添加到收藏中或从收藏中删除照片。

这是一个“编辑多个”情况,所以我创建了两个新的控制器操作:select,处理 GET 请求和视图,assign,处理来自选择视图中复选框的 PUT 请求。

因为用户可以将照片添加到收藏夹或从收藏夹中删除照片,所以我的 assign 操作中有一个条件,它看起来像这样:

def assign
    @photos = Photo.find(params[:photo_ids])
    case params[:assignment]
    when 'add'
        @photos.each do |p|
            p.collection = @collection
            p.save!
        end
        notice = "Photos added to collection."
    when 'remove'
        @photos.each do |p|
            p.collection = nil
            p.save!
        end
        notice = "Photos removed from collection."
    end
    redirect_to select_collection_photos_path(@collection), :notice => notice
end

这完全符合预期。但是,我对此感到不舒服,它似乎不符合“Rails Way”。

其他 Rails 开发者,当你遇到这种情况时,你会像我一样处理吗?您会将其拆分为两个控制器操作(即add_to_collectionremove_from_collection),还是将其移至模型?如果你要将它移到模型上,那会是什么样子?

如果有任何建议和反馈,我将不胜感激。谢谢!

【问题讨论】:

  • 如果用户选择一个新的复选框,取消选择之前选择的复选框,然后保存会发生什么? “添加”和“删除”在哪里设置?
  • 它们是同一视图中的两种不同形式,它们有一个隐藏字段,用于指定是否应将给定 id 的照片添加到集合中或从集合中删除。

标签: ruby-on-rails ruby-on-rails-3 model controller


【解决方案1】:

可能有几种不同的方法可以重构它,但最明显的一种似乎是将所有照片逻辑移至照片模型。即使这是您的照片控制器,它也不应该对照片模型了解太多。

我可能会在您的控制器中按照以下方式做一些事情:

def assign
  Photo.update_collection(params, @collection)

  redirect_to select_collection_photos_path(@collection), :notice => "Photo collection updated"
end

然后在你的照片模型中:

class Photo < ActiveRecord::Base
  def self.update_collection(params, collection)

    photos = Photo.find(params[:photo_ids])

    case params[:assignment]
    when 'add'
      photos.each {|p| p.add_collection(collection) }
    when 'remove'
      photos.each {|p| p.remove_collection }
    end
  end

  def add_collection(collection)
    self.collection = collection
    save!        
  end

  def remove_collection
    self.collection = nil
    save!
  end
end

将功能分解为更小的模型方法可以更轻松地进行单元测试,如果你不这样做,你应该这样做:)

【讨论】:

    【解决方案2】:

    这实际上是accepts_nested_attributes_for 的主要候选者。

    不要考虑控制器中的新操作,而是尽可能坚持标准的 REST 约定。除了花哨的 UI 显示内容(例如您的选择操作),我很少发现我需要偏离生成的脚手架控制器中存在的标准 CRUD 操作。

    如果你在你的照片模型中设置了accepts_nested_attributes_for :collection,你应该能够建立一个特殊的表单来为照片分配集合。我不会在这里详细介绍,而是将您指向 http://railscasts.com/episodes/196-nested-model-form-part-1http://railscasts.com/episodes/197-nested-model-form-part-2 。视图中的工作量会更大,但您会在更简单、易于测试的控制器和模型方面遥遥领先。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-10-24
      • 2014-03-24
      • 2010-09-22
      • 2013-11-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多