RoR 允许非模型参数

RoR permitting non model parameter

我很难理解如何允许非模型参数。

我读过:

因此,对于 "normal" 情况 - 假设我有一个模型 Foo,它只有一个属性 bar:

# foo.rb
class Foo < ActiveRecord::Base
  # bar, which is a integer
end

# views/foos/new.html.erb
<%= form_for @foo do |f| %>
    <%= f.number_field :bar %>
    <%= f.submit %>
<% end %>

#foos_controller.rb
def create
    @foo = Foo.new(foo_params)
    # ...
end

#...

private

def foo_params
    params.require(:foo).permit(:bar)
end

因此,当我提交表单时,将创建 Foo


但是,如果 bar 属性背后有一些结合了一些非模型参数的逻辑怎么办?假设 bar 是两个参数 (bar = bar_1 + bar_2) 的总和。然后视图和控制器看起来像:

# views/foos/new.html.erb
<%= form_for @foo do |f| %>
    <%= f.number_field :bar_1 %>
    <%= f.number_field :bar_2 %>
    <%= f.submit %>
<% end %>

#foos_controller.rb
def create
  bar_1 = params[:foo][:bar_1]
  bar_2 = params[:foo][:bar_2]

  if bar_1.present? && bar_2.present?
    @foo = Foo.new
    @foo.bar = bar_1.to_i + bar_2.to_i

    if @foo.save
      # redirect with success message
    else
      # render :new
    end
  else
    # not present
  end
end

所以问题是,我还需要允许 bar_1bar_2 参数吗?如果我这样做,我该如何允许它们?

如果你想访问这两个非模型参数,你必须通过下面的代码在你的Foo模型上将它与模型绑定

attr_accessor :bar_1, :bar_2

不需要在

中允许
def foo_params
   params.require(:foo).permit(:bar)
end

注意:确保将其从 params 中删除,它不会引发任何错误,但会在 rails console 上向您发出警告,例如 Unpermitted parameters: bar_1, bar_2

无需允许 bar_1 和 bar_2 参数,除非您在 foo 下创建它们。但在您的情况下,您是在 foo 下创建的。最好的解决方案是创建 attr_accessor

# foo.rb
class Foo < ActiveRecord::Base
  # bar, which is a integer
  attr_accessor :bar_1, bar_2
end

# views/foos/new.html.erb
<%= form_for @foo do |f| %>
    <%= f.number_field :bar_1 %>
    <%= f.number_field :bar_2 %>
    <%= f.submit %>
<% end %>

#foos_controller.rb
def create
  bar_1 = params[:foo][:bar_1]
  bar_2 = params[:foo][:bar_2]

  if bar_1.present? && bar_2.present?
    @foo = Foo.new
    @foo.bar = bar_1.to_i + bar_2.to_i

    if @foo.save
      # redirect with success message
    else
      # render :new
    end
  else
    # not present
  end
end

第一个选项:将逻辑放入模型中:

允许 bar1bar2

def foo_params
  params.require(:foo).permit(:bar1, :bar2)
end

然后在你的模型中处理这个逻辑:

class Foo < ActiveRecord::Base
  attr_accessor :bar1, bar2

  after_initialize :set_bar

  def set_bar
    self.bar = bar1 + bar2 if bar_1 && bar_2
  end
end

第二个选项:创建一个formatted_params方法:

# views/foos/new.html.erb
<%= form_for @foo do |f| %>
    <%= f.number_field :bar_1 %>
    <%= f.number_field :bar_2 %>
    <%= f.submit %>
<% end %>

#foos_controller.rb
def create
    @foo = Foo.new(formatted_params)

    if @foo.save
      # redirect with success message
    else
      # render :new
    end
end

def permitted_params
  params.require(:foo).permit(:bar_1, :bar2)
end

def formatted_params
  bar1 = permitted_params.delete(:bar1)
  bar2 = permitted_params.delete(:bar2)
  permitted_params.merge(bar: bar1 + bar2)
end