Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ruby-on-rails-3/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby on rails Rails最佳实践:条件操作、多个操作还是方法?_Ruby On Rails_Ruby On Rails 3_Model_Controller - Fatal编程技术网

Ruby on rails Rails最佳实践:条件操作、多个操作还是方法?

Ruby on rails Rails最佳实践:条件操作、多个操作还是方法?,ruby-on-rails,ruby-on-rails-3,model,controller,Ruby On Rails,Ruby On Rails 3,Model,Controller,我很想得到一些关于我最近正在编写的代码块的信息 我有一个模型,照片,有时(但不总是)属于收藏。我有一个页面供用户管理收藏,他们可以将任何未分配的照片添加到收藏或从收藏中删除照片 这是一种“编辑多个”的情况,因此我创建了两个新的控制器操作:select,它处理GET请求和视图,以及assign,它处理来自select视图中复选框的PUT请求 由于用户可以向收藏中添加照片,也可以从收藏中删除照片,因此我的assign操作有一个条件,如下所示: def assign @photos = Pho

我很想得到一些关于我最近正在编写的代码块的信息

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

这是一种“编辑多个”的情况,因此我创建了两个新的控制器操作:
select
,它处理GET请求和视图,以及
assign
,它处理来自select视图中复选框的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方式”

其他Rails开发人员,当您遇到这种情况时,您会像我一样处理它吗?您是将其拆分为两个控制器操作(即
将\u添加到\u集合
从\u集合中删除\u
),还是将其移动到模型中?如果将其移动到模型中,会是什么样子


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

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

我可能会在您的控制器中执行以下操作:

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
class-Photo

将功能分解为更小的模型方法可以更容易地进行单元测试,如果您不是:)

这实际上是接受嵌套属性的主要候选对象

不要考虑控制器中的新操作,只要有可能,就坚持标准的REST约定。除了花哨的UI显示功能(比如选择操作),我很少发现我需要偏离生成的scaffold\u控制器中的标准CRUD操作


如果在照片模型中为:集合设置accepts_nested_attributes_,则应该能够构建一个特殊表单,将集合指定给照片。我不会在这里详细介绍,但会向您指出和。在视图中需要做更多的工作,但在更简单、易于测试的控制器和模型中,您将遥遥领先。

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