Schienen — zum Auffüllen der id des übergeordneten Objekts verwenden von geschachtelten Attribute für untergeordnete Objekt und starken Parameter?

Habe ich eine situation ähnlich wie dargestellt in Railscast 196-197: Nested-Modell-Form. Allerdings habe ich festgestellt ein Konflikt zwischen diesem Ansatz und der starken Parameter. Ich kann nicht herausfinden, eine gute Möglichkeit zum Auffüllen des parent-record Feld-id für das untergeordnete Objekt, da ich nicht möchte, dass sein belegbar durch die form (zu verhindern, dass Benutzer zuordnen untergeordneten Datensätze zu übergeordneten Datensätze, die Sie nicht besitzen). Ich habe eine Lösung (siehe code unten), aber dies scheint die Art von Sache, die Schienen könnten mit einem cleveren, einfach Weg, dies zu tun für mich.

Hier ist der code...

Gibt es ein parent-Objekt (nennen wir es Umfrage), dass has_many untergeordneten Objekte (nennen wir Sie Fragen):

# app/models/survey.rb
class Survey
    belongs_to :user
    has_many :questions
    accepts_nested_attributes_for :questions
end

# app/models/question.rb
class Question
    validates :survey_id, :presence => true
    belongs_to :survey
end

Gibt es ein Formular, das Benutzern erlaubt, um eine Umfrage zu erstellen und die Fragen, die auf die Umfrage zur gleichen Zeit (für die Einfachheit, den code unten Umfragen behandelt, als hätten Sie nur die Frage):

# app/views/surveys/edit.html.erb
<%= form_for @survey do |f| %>
    <%= f.label :name %>
    <%= f.text_field :name %><br />
    <%= f.fields_for :questions do |builder| %>
        <%= builder.label :content, "Question" %>
        <%= builder.text_area :content, :rows => 3 %><br />
    <% end %>
    <%= f.submit "Submit" %>
<% end %>

Das problem ist der controller. Ich möchte zum Schutz der survey_id Feld auf die Frage, Datensatz über starke Parameter, aber dabei die Fragen, die don ' T-pass-Validierung, da die survey_id ist ein erforderliches Feld.

# app/controllers/surveys_controller.rb
class SurveysController
    def edit
        @survey = Survey.new
        Survey.questions.build
    end

    def create
        @survey = current_user.surveys.build(survey_params)
        if @survey.save
            redirect_to @survey
        else
            render :new
        end
    end

    private

    def survey_params
        params.require(:survey).permit(:name, :questions_attributes => [:content])
    end
end

Die einzige Möglichkeit die ich denken kann, um dieses problem zu lösen, ist das erstellen der Fragen getrennt von der Umfrage wie diese:

def create
    @survey = current_user.surveys.build(survey_params)
    if @survey.save
        if params[:survey][:questions_attributes]
            params[:survey][:questions_attributes].each_value do |q|
                question_params = ActionController::Parameters.new(q)
                @survey.questions.build(question_params.permit(:content))
            end
        end
        redirect_to @survey
    else
        render :new
    end
end

private

def survey_params
    params.require(:survey).permit(:name)
end

(Rails 4 beta 1 Ruby 2)

UPDATE

Vielleicht der beste Weg, dieses problem zu behandeln, ist die Faktor, eine "Form Objekt", wie vorgeschlagen, in dieser Code Klima-blog-post. Ich lasse die Frage offen, obwohl, wie ich bin neugierig auf andere Sichtweisen

  • haben Sie herausfinden, wie man dieses Problem beheben, mithilfe einer geschachtelten form?
Schreibe einen Kommentar