2016-08-01 17 views
2

Ich habe eine harte Zeit zu versuchen, zu verstehen, wie man nicht-Modell-Parameter zu ermöglichen.RoR erlaubt nicht Modell Parameter

Ich habe gelesen:

Also, für eine "normale" Situation - lassen Sie uns sagen, dass ich ein Modell Foo haben, die gerade hat ein Attribut 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 

Also, wenn ich das Formular abschicken, wird die Foo erstellt.


Was aber, wenn das Attribut bar eine gewisse Logik dahinter ist, dass kombiniert einige nicht Modellparameter? Nehmen wir an, dass bar die Summe zweier Parameter ist (bar = bar_1 + bar_2). Dann wird die Ansicht und Controller wie folgt aussieht:

# 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 

Die Frage ist also, kann ich auch die bar_1 und bar_2 Parameter erlauben müssen? Wenn ich es tue, wie erlaube ich ihnen?

Antwort

1

erste Option zu erstellen: die Logik im Modell setzen:

Permit bar1 und bar2:

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

Dann diese Logik in Ihrem Modell Griff:

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 
Erstellen eine formatted_params Methode:

Zweite Option

# 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

In der ersten Option, Wenn ich nicht verwenden 'foo_params' für die erstellen/aktualisieren, ist das Verfahren dann wirklich benötigt? – Vucko

+0

Ja. Du würdest weiterhin 'Foo.new (foo_params)' machen. – lcguida

+0

Ich denke, ich habe es.Prost – Vucko

3

Wenn Sie diese beiden nicht-Modellparameter zugreifen möchten, müssen Sie es mit dem Modell binden, indem Sie Code auf Ihrem Foo Modell

attr_accessor :bar_1, :bar_2 

Keine Notwendigkeit, es zu ermöglichen, in

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

Hinweis: Stellen Sie sicher, dass Sie es von Ihrem params entfernen, es wird keinen Fehler auslösen, aber Sie erhalten eine Warnung auf rails console wie Unpermitted parameters: bar_1, bar_2

1

Sie müssen die Parameter bar_1 und bar_2 nicht zulassen, es sei denn, Sie erstellen sie unter foo. Aber in Ihrem Fall erstellen Sie in unter foo. Die beste Lösung ist 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