Rails - 2 forms one model - ruby-on-rails

I'm struggling with this one, basically I want two forms to submit to the one model. When the first form is complete, the second one is rendered which will contain the remaining information which the model requires. Ideally I would like to combine the two returned hashes and save them together at once. If there is a more sensible way of doing this please let me know. Thanks in advance.
app/controllers/books_controller.rb
class BooksController < ApplicationController
def new
#book = #library.books.build
#user = current_user
end
def create
#book = #library.books.build(params[:book])
if #book.total_pages.nil?
#book_first_page = #book
render 'new'
else
#book.update_attributes(#book_first_page)
if #book.save
redirect_to root_path
else
render 'new'
end
end
end
end
app/views/books/new.html.erb
<% if #book.title.nil? %>
<%= form_for [:library, #book] do |f| %>
<%= render 'shared/error_messages', object: f.object %>
<div class="form-group input-group-sm">
<%= f.label :title, 'What is the title of the book?' %>
<%= f.text_area :title, class: "form-control" %>
</div>
<%= f.submit "Submit Title", class: "btn btn-large btn-primary" %>
<% end %>
<% else %>
<%= form_for [:library, #book] do |f| %>
<%= render 'shared/error_messages', object: f.object %>
<div class="form-group input-group-sm">
<%= f.label :total_pages, "How many pages?:" %>
<%= f.text_field :total_pages, class: "form-control" %>
</div>
<%= f.submit "Submit Number of Pages", class: "btn btn-large btn-primary" %>
<% end %>

You might also use a single form for all your data, but initially showing only the first portion of the form, and then employ javascript to hide the first part and show the second part when the first part is complete.

You should consider using accepts_nested_attributes_for
For example, see http://railscasts.com/episodes/196-nested-model-form-revised

why you need to update in two form. use just one form

Related

Want to make a button that clears a form after saving the data in a form as an object

So I'm doing a project in Ruby, and I want to have people fill out a form , which will be an answer to a question, and be able to make another answer to that same question. To accomplish this, I would like to save an answer object to my database using the data in the form, and then clear the form. I've yet to figure out how to do that using a link_to tag.
Here is the object controller:
class AnswersController < ApplicationController
def index
#answers = Answer.all
end
def new
#answer = Answer.new
end
def show
#answer = Answer.find(params[:id])
end
def create
Question.order (:created_at)
#question = Question.last
#answer = #question.answers.build(answer_params)
#if #answer.save
# redirect_to root_url
#else
# render static_pages/home
#end
redirect_to root_url
end
private
# Never trust parameters from the scary internet, only allow the white list through.
def answer_params
params.require(:answer).permit(:content, :correct)
end
end
Here is the new.html.erb:
<% provide(:title, 'New Answers') %>
<h1>New Answers</h1>
<div class="row">
<div class="col-md-6 col-md-offset-3">
<%= form_for(#answer) do |f| %>
<%= render 'shared/error_messages', object: f.object %>
<%= f.label #content%>
<%= f.text_field #content, class: 'form-control' %>
<%= f.label #correct%>
<input type="checkbox" name="Correct?" value="Correct?" checked> This answer is correct<br>
<%= f.submit "Finish creating Quiz", class: "btn btn-primary" %>
<%= link_to "Create more Questions", createQuestion_path, class: "btn btn-primary" %>
<%= link_to "Create more Answers", createAnswer_path, class: "btn btn-primary" %>
<% end %>
</div>
</div>
Any help would be appreciated. Please let me know if you need anything else to further understand the problem
Thanks!
The easiest way to do this is to redirect back after the form has been submitted. But if you want to this dynamically, you'll have to add some JavaScript on top.
So, for example, you could make an AJAX POST request on submission, perhaps add some indication of that action happening and then clear the fields using Jquery or plain JavaScript.
There are meriad of ways to this, you can read more on this here. It might look something like this:
Controller
def create
respond_to do |format|
#question = Question.last
#answer = #question.answers.build(answer_params)
if #answer.save
format.json { head :no_content }
else
format.json do
render json: {
errors: #answer.errors.full_messages
}, status: :unprocessable_entity
end
end
end
View
<% provide(:title, 'New Answers') %>
<h1>New Answers</h1>
<div class="row">
<div class="col-md-6 col-md-offset-3">
<%= form_with(#answer) do |f| %>
<%= render 'shared/error_messages', object: f.object %>
<%= f.label #content%>
<%= f.text_field #content, class: 'form-control' %>
<%= f.label #correct%>
<input type="checkbox" name="Correct?" value="Correct?" checked> This answer is correct<br>
<%= f.submit "Finish creating Quiz", class: "btn btn-primary" %>
<%= link_to "Create more Questions", createQuestion_path, class: "btn btn-primary" %>
<%= link_to "Create more Answers", createAnswer_path, class: "btn btn-primary" %>
<% end %>
</div>
</div>
JavaScript
$(document).ready(function() {
$("#new_answer").on("ajax:success", function(e, data, status, xhr) {
$('#yourForm').trigger("reset");
}).on("ajax:error", function(e, xhr, status, error) {
$("#new_answer").append("<p>ERROR</p>");
});
});

Redirecting submit button to the same page

could someone show me a way of making my button redirect to the same page that the submission took place. Here is what my form looks like:
<%= form_for Event.new do |f| %>
<%= f.text_field :partycode %>
<%= f.submit "Submit", class: "btn btn-primary" %>
<% end %>
Thanks in advance :)
This is a weird question, but I'm assuming you want the same view (i.e. page).
What you want to do is render the form again.
This is accomplished by overriding which view is rendered by your controller action.
def new # renders new.(format) by default
#event = Event.new
end
def create
#event = Event.new(event_params)
if #event.save
# ...
else
# ...
end
render 'new' # overrides default behaviour
end
Then assuming you have the following views:
# app/views/events/_form.html.erb
<%= form_for #event do |f| %>
<%= f.text_field :partycode %>
<%= f.submit "Submit", class: "btn btn-primary" %>
<% end %>
# app/views/events/new.html.erb
<%= render 'form' %>

Incrementing model integer via custom method and form_for

I'm extremely new to Rails and so I apologize if this is a simple question. I am attempting to build a simple site that allows users to vote as whether or not they liked the lunch that day. Lunches are associated with providers (restaurants) and thus providers will have many different "lunches."
I know it is possible to auto increment by adding this to a method in the controller (discussed more here) and my current setup looks like this:
The view:
<%-# Show current like and dislike counts. -%>
<div> Likes: <%= #lunch.liked %> </div>
<div> Dislikes: <%= #lunch.disliked %> </div>
<div>
<%= form_for :lunch url: lunch_path, method: :put do |f| %>
<div><%= f.hidden_field :disliked %></div>
<div><%= f.hidden_field :id %></div>
<%= f.submit "Disike Lunch", class: "btn btn-large btn-primary" %>
<% end %>
</div>
The controller:
def downvote_lunch
#lunch = Lunch.find(params[:id])
#lunch.increment!(:disliked)
redirect_to lunch_path
end
Routes:
resources :lunches
...
match '/dislike', to: 'lunches#downvote_lunch', via: 'get'
However, when I click on the "Dislike Button" it tells me that there is no view for "update" - I've defined update as an empty method in the controller, but I'm not sure why it's accessing update - all I'm looking for is to reload lunches/:id with the updated count for "disliked."
My question: How do I get the form to point to the custom "downvote_lunch" method, and have it redirect back to the lunches/:id after successfully incrementing the "dislikes" integer in the model?
For it you have to do
In view
<div>
<%= form_for :lunch url: downvote_lunch_lunch_path(params[:id]), method: :put do |f| %>
<div><%= f.hidden_field :disliked %></div>
<div><%= f.hidden_field :id %></div>
<%= f.submit "Disike Lunch", class: "btn btn-large btn-primary" %>
<% end %>
</div>
In routes
resources :lunches do
member do
put :downvote_lunch
end
end
In controller
def downvote_lunch
#lunch = Lunch.find(params[:id])
#lunch.increment!(:disliked)
redirect_to #lunch
end
it will work as you want

Save as new record in edit action

Views: _form.html.erb
<%= form_for(#product) do |f| %>
<div class="field">
<%= f.label :name %><br />
<%= f.text_field :name %>
</div>
<div class="field">
<%= f.label :price %><br />
<%= f.number_field :price %>
</div>
<div class="actions">
<%= f.submit "Save" %>
<% if params[:action] == "edit" %>
<% f.submit "Save As New" %>
<% end %>
</div>
<% end %>
edit.html.erb
<%= render 'form' %>
In my products controller I have all the new,create,edit & update actions normally defined.
Question: This form update is working fine but I have a new submit button called "Save As New" is it anyway possible to invoke a create action inside the edit products page, when a user clicks on that.
I know the possibility to use a condition and check if params[:commit]=="Save As New" and try to invoke another action but I am not really sure if I can do that. How should I update my controller to make it work.
Thanks a ton.
You can change the update action like this:
if params[:commit]=="Save As New"
#product = Product.create(params[:product])
else
#product.update_attributes(params[:product])
end
redirect_to #product
So you wont need a new action and can handle it without adding routes...
If I'm understanding it correctly, you want the user to be able to create a new record from inside in the edit page, right?
If that's the case, I think you can do this:
<div class="actions">
<%= f.submit "Save" %>
<% if params[:action] == "edit" %>
<%= link_to "Save As New", {controller: 'products',
action: 'new'
},
class: "if there's a css class"} %>
<% end %>
</div>

Multiple instances of one form_for on a single page? Rails

Thank you in advance,
I have a simple Document model and form_for to create a new document.
All I would like to do is have multiple - say 3 - forms on one page which will create three separate model instances. Either seperate 'submit' buttons or one main one
new.html.erb:
<% 3.times do %>
<%= render 'documents/new_document_form' %>
<% end %>
_new_document_form.html.erb
<%= form_for #document do |f| %>
<%= f.label :title %>
<%= f.text_field :title %>
<%= f.file_field :document_file %>
<%= f.submit "Save Changes", class: "btn btn-large btn-primary" %>
<% end %>
documents_controller.rb
def new
#document = current_account.documents.build if signed_in?
end
def create
#document = current_account.documents.build(params[:document])
if #document.save
flash[:success] = "Successful document upload!"
redirect_to documents_path
else
flash[:error] = "Please try again"
render 'new'
end
end
I could use some help understanding:
how to create multiple unique instances of the forms
pass the input successfully to the controller
any more info!

Resources