使用方法请求对象的最佳实践

时间:2016-02-19 13:29:40

标签: ruby-on-rails

阅读并做一些RoR教程,他们说我们应该有一个私有方法来请求一个对象并指出它的属性。例如:

  def category_params
    params.require(:category).permit(:name)
  end

当我创建一个新类别(本例中的数据)时,我在创建操作中使用:

@category = Category.new(category_params)

但是,当我更新某个类别时,我无法@category = Category.new(category_params),因为:category并未在params中返回。对于这种情况,我在this question的comentaries中看到require(:category)需要移除到更新操作工作。这解决了问题,但换句话说,当我使用category_params创建新类别时,总是会保存一个空对象。

有两个私有方法,on require和其他没有isn不是一个好习惯,或者是?在这种情况下,有什么好的做法?

编辑1(我的更新和编辑操作):

def edit
  @category = Category.find(params[:id])
end

def update
  @category = Category.find(params[:id])

  if @category.update_attributes(category_params)
    # TO DO
  else
    render 'edit'
  end
end

1 个答案:

答案 0 :(得分:2)

我认为你只是对强大的参数应该做什么感到困惑 - 它基本上只是质量分配的白名单参数。

批量分配是指使用散列中的属性或散列更新来实例化新记录。尽管您通常使用update代替#update,但#update_attibutes行动完全正常。

执行此操作的明智方法是在控制器中使用私有方法,这样您就不必在更新和创建操作中两次执行完全相同的白名单。

class CategoriesController

  before_action :set_category, only: [:show, :edit, :update, :destroy]

  def new
    @category = Category.new
  end

  def create
    @category = Category.create(category_params)
    respond_with(@category)
  end

  def edit
  end

  def update
    if @category.update(category_params)
    # TO DO
    else
      render 'edit'
    end
  end

  # ...

  private

    def set_category
      @category = Category.find(params[:id])
    end

    def category_params
      params.require(:category).permit(:name, :foo, :bar)
    end

end

我们设置表格如下:

app/views/categories/_form.html.erb

<%= form_for(@category) do |f| %>
  <div class="field">
    <%= f.label :name %>
    <%= f.text_field :name %>
  </div>

  <%= f.submit %>
<% end %>

我们可以使用完全相同的表格来创建新记录和编辑。

应用程序/视图/类别/ new.html.erb:

<%= render partial: "form" %>

应用程序/视图/类别/ update.html.erb:

<%= render partial: "form" %>

请注意,在某些情况下,您可能希望为一个操作允许某些属性,而对另一个操作则不允许。在这种情况下,您只需创建两个强大的参数方法:

class CategoriesController

  before_action :set_category, only: [:show, :edit, :update, :destroy]

  def new
    @category = Category.new
  end

  def create
    @category = Category.create(create_params)
    respond_with(@category)
  end

  def edit
  end

  def update
    if @category.update(update_params)
    # TO DO
    else
      render 'edit'
    end
  end

  # ...

  private

    def set_category
      @category = Category.find(params[:id])
    end

    def create_params
      params.require(:category).permit(:name, :foo, :bar)
    end

    def update_params
      params.require(:category).permit(:name)
   end

end