How to “Create” after second step _form?

2019-09-02 14:26发布

So in step one the user creates his challenge.

<%= form_for(@challenge) do |f| %>
  <%= f.text_field :action %>
  <%= f.submit %>
<% end %>

Then he is directed to another _form to finish adding details about that challenge.

<%= form_for(@challenge) do |f| %>
  <%= f.text_field :action %>
  <%= f.date_select :deadline %>
  <%= f.check_box :conceal %>
  <%= f.submit %>
<% end %>

Once he adds those details and clicks "Save" I want the challenge to be created via the Create action of the challenges_controller.

def step_one
  ??
end

def create
  @challenge = Challenge.new(challenge_params)
  @challenge.save
  redirect_to challenging_url(@challenge)
end

2条回答
做个烂人
2楼-- · 2019-09-02 14:58

The answer is more likely "it depends what you are trying to do", but the simplest solution is to redirect (in create after save) to the edit action/view which contains all or the other fields, not just the limited fields you provided in the new action/view.

def create
  @challenge = Challenge.new(challenge_params)
  if @challenge.save
    redirect_to edit_challenge_url(@challenge), notice: "Saved!"
  else
    render :new
  end
end
查看更多
成全新的幸福
3楼-- · 2019-09-02 15:13

If you want to create a record across two requests, you need to persist data from the first request, and re-submit it along with the second request.

The easiest and most "Rails"y way of accomplishing this is to accept the incoming "name" attribute from your first request and render the second stage form with the name persisted as a hidden field.

app/controllers/challenge_controller

# Show "step 1" form
def new
  @challege = Challenge.new
end

# Show "step 2" form, OR, attempt to save the record
def create
  @challenge = Challenge.new(params[:challenge])

  if params[:step] == '2'
    if @challenge.save
      redirect_to @challenge, notice: "Challenge saved!"
    end
  end
  # Fall through to render "create.html.erb"
end

app/views/challenges/new.html.erb

<%= form_for @challenge do |f| %>
  <%= f.input_field :name %>
  <%= f.submit %>
<% end %>

app/views/challenges/create.html.erb

<%= form_for @challenge do |f| %>
  <%= f.hidden_field :name %>
  <%= hidden_field_tag :step, 2 %>
  <%= f.text_field :action %>
  <%= f.date_select :deadline %>
  <%= f.check_box :conceal %>
  <%= f.submit %>
<% end %>

There are a few things to note here:

  • create renders a different form than new. This is atypical for a Rails application
  • The "step 2" form rendered by create uses hidden_field_tag to attach an extra value to the submission, outside of the params[:challenge] attributes
  • Validation is unhandled - it's up to you to display errors if somebody submits an empty name in step 1, or other invalid attributes in step 2
查看更多
登录 后发表回答