2016-08-01 33 views
2

我很难试图了解如何允许非模型参数。RoR允许非模型参数

我读过:

所以,对于一个 “正常” 的情况 - 让我们说,我有一个具有只是一个模型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参数?如果我这样做,我该如何准许他们?

回答

1

第一个选项:把逻辑模型:

许可证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_pa​​rams方法:

# 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 
+0

在第一个选项,如果我不使用'foo_params'为创建/更新,然后方法真正需要的? – Vucko

+0

是的。你会继续做'Foo.new(foo_params)'。 – lcguida

+0

想我明白了。干杯 – Vucko

3

如果要访问这两个非模型参数,你必须与模型通过下面的代码对你的Foo模型

attr_accessor :bar_1, :bar_2 

没有必要允许它在其绑定

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

注意:确保你从params中删除它,它不会引起任何错误,但给你一个警告rails consoleUnpermitted parameters: bar_1, bar_2

1

除非您在foo下创建它们,否则不需要允许bar_1和bar_2参数。但在你的情况下,你正在富有创造。最好的解决办法是创建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