Rails最佳实践:条件操作,多个操作或方法?

时间:2011-03-06 04:19:59

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

我很想获得一些我最近一直在处理的代码的输入。

我有一个模型,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)之间拆分它,还是将它移动到模型中?如果你要将它移到模型中,那会是什么样的?

我很感激任何建议和反馈。谢谢!

2 个答案:

答案 0 :(得分:2)

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

我可能会在你的控制器中沿着这些方向做点什么:

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

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

答案 1 :(得分:0)

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

不要考虑控制器中的新操作,只要有可能,请坚持使用标准REST约定。除了花哨的UI显示内容(比如你的选择动作),我很少发现我需要偏离生成的scaffold_controller中存在的标准CRUD操作。

如果在Photo模型中设置accepts_nested_attributes_for:collection,则应该能够构建一个特殊的表单,将集合分配给照片。我不会在此处详细介绍完整的详细信息,而是指向http://railscasts.com/episodes/196-nested-model-form-part-1http://railscasts.com/episodes/197-nested-model-form-part-2。在视图中,这将是更多的工作,但你会在更简单,易于测试的控制器和模型中走得更远。