Save as new record in edit action - ruby-on-rails

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>

Related

rails submit_tags to different actions

<%= simple_form_for#equipment, :url => equipments_path, :method => :post do |f| %>
....
<% if #equipment.id.present? %>
<div class="actions">
//TODO submit_tag to action Update
</div>
<% else %>
<div class="actions">
<%= submit_tag "Adicionar Equipamento" %>
</div>
<% end %>
<% end %>
In this example I have two buttons,if the object exists I have the first button and when not exists I have the second button. The second button send a request to controller Equipments#Create. How can I send a request to Equipments#Update in first button ?
<%= simple_form_for #equipment do |f| %>
<div class="actions">
<%= submit_tag(#equipment.persisted? ? "Create Equipment" : "Update Equipment") %>
</div>
<% end %>
This is the short way to do it.
Usually you would use I18n to translate these labels.
(see: I18n for model-specific Rails submit button)

Edit and update issue

New and Create are working good, data is stored in the database but edit and update is having issues.
This is my sages controller sages_controller.rb
class SagesController < ApplicationController
def home
end
def about
end
def new
#sage = Sage.new
end
def create
#sage= Sage.new(sage_params)
if #sage.save
flash[:success] = 'Thanks for Joining'
redirect_to '/thanks'
else
flash[:notice] = 'Please fill the form Correctly'
render 'new'
end
end
def edit
#sage=Sage.find(params[:id])
end
def update
#sage = Sage.find(params[:sage])
if #sage.update_attributes(sage_params)
redirect_to '/thankss'
else
render 'new'
end
end
def resources
end
private
def sage_params
params.require(:sage).permit(:Name, :Email, :Address, :Number)
end
end
THis is my view for new method new.html.erb
<div class="contact" style="padding: 50px; color: orange ">
<%= form_for #sage do |f| %>
<div class="form-group" >
<h3><%= f.label :Name%></h3>
<%= f.text_field :Name %>
<br/>
</div>
<div class="form-group" >
<h3><%= f.label :Email%></h3>
<%= f.email_field :Email %>
</div>
<div class="form-group" >
<h3><%= f.label :Address%></h3>
<%= f.text_field :Address %>
<br/>
</div>
<div class="form-group" >
<h3> <%= f.label :Number%></h3>
<%= f.number_field :Number %>
<br/>
</div>
<br/>
<br/>
<div class="submit" >
<h2><%= f.submit 'SUBMIT'%></h2>
</div>
<% end %>
<%= link_to 'Edit', 'edit' %>
</div>
`
This is my view for Edit method edit.html.erb
<%= form_for #sage do |f| %>
<%= f.label :Name %>
<%= f.text_field :Name %>
<br/>
<%= f.label :Email %>
<%= f.text_field :Email %>
<br/>
<%= f.label :Address %>
<%= f.text_field :Address %>
<br/>
<%= f.label :Number %>
<%= f.text_field :Number %>
<br/>
<%= f.submit 'Update' %>
<% end %>
`
This is my routes in routes.rb
resources :sages,only: [:new,:create,:edit, :update]
get 'sages/home'=>'sages#home'
get 'sages/about'=>'sages#about'
get 'sages/resources'=>'sages#resources' `
You are doing it wrong, how can you edit a record if it doesn't exist. In new.html.erb you have added a link
<%= link_to 'Edit', 'edit' %>
Remove that line, its wrong. You can only edit an existing record and not a new record. Also, the route is wrong. It should look something like
<%= link_to 'Edit', edit_sage_path(#sage) %>
Hope this helped!
Which URL or path you are using? I imagine you are using an incorrect URL or path.
With the routes you mentioned you should have the following access route for edit:
edit_sage GET /sages/:id/edit(.:format) sages#edit
So either you use edit_sage(id) or you type in the URL with /sages/id/edit. Please note that you have to replace id (in path or URL) by a valid id of a sage.
In the new view you cannot edit an object that does not exist (i.e. is not persisted in database).
<%= link_to 'Edit', 'edit' %>
is wrong as mentioned by other users.
Also if ever you want to call edit, consider what I mentioned in the beginning. Make sure you pass a valid id or sage object that effectively exists in database.
First thing you need to change edit link, it should be like :
<%= link_to 'Edit', edit_sage_path(#sage) %>
Second thing you can't call edit link in your new template because in this case you have #sage is empty (it just initiated),you can edit your sage by adding 'Edit' link to either index or show template
in update action change
def update
#sage = Sage.find(params[:id])
if #sage.update_attributes(sage_params)
redirect to ('/thanks')
else
render 'new'
end
end
Like an example if you have record with id = 2 then write url like /sages/2/edit and you will get data with record id=2.
Do this below change in your update method also,
#sage = Sage.find_by_id(params[:id])
The link i gave was wrong for edit in new.html.erb, removed it
and changed the route of edit to:
get 'sages/id/edit'=>'sages#edit' in routes.rb and now it works fine....

Posting a variable to another controller

I have a welcome controller/view.
On the index.html.erb I have a simple form that takes in one value:
<%= form_tag do %>
<div>
<%= label_tag(:zip, "Enter Zipcode to search in:") %>
<%= text_field_tag(:zip) %>
</div>
<%= submit_tag("Search") %>
<% end %>
Upon hitting the submit button I'd like to pass the zip variable to another controller called "theaters". The variable doesnt need to be saved in any kind of model, its just being used to execute an API call in the Theaters controller.
Whats the simplest way to do this?
Thanks
Try this:
<%= form_tag({controller: "theaters", action: "index"}) do %>
<div>
<%= label_tag(:zip, "Enter Zipcode to search in:") %>
<%= text_field_tag(:zip) %>
</div>
<%= submit_tag("Search") %>
<% end %>
Hope it helps.
Make a route for your method in TheatresController, lets assume your method name is get_zip
post '/get_zip' => 'theaters#get_zip', as: "zip"
Create your form
<%= form_tag(url: zip_path, method: :post) do %>
<div>
<%= label_tag(:zip, "Enter Zipcode to search in:") %>
<%= text_field_tag(:zip) %>
</div>
<%= submit_tag("Search") %>
<% end %>
Access it inside your method:
def get_zip
#zip = params[:zip]
#your logic
end

Rails - 2 forms one model

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

Rails and Ajax how to correctly handle ajax request

I have a Projects controller and in the "new.html.erb" view i've the following code:
<div class="row">
<%= form_for #project, remote: true do |f| %>
<%= f.label :name %>
<%= f.text_field :name %>
<%= f.label :description %>
<%= f.text_field :description %>
<%= f.submit "Add Project", class: "btn btn-primary"%>
<% end %>
</div>
<p id= "test">Hello</p>
When i click on the submit button i know that is called the "create" action in the Projects controller:
def create
respond_to do |format|
format.html{ redirect_to new_project_path}
format.js
end
end
I have created the create.js.erb file to handle the ajax request:
("#test").hide()
Why the
<p id= "test">Hello</p>
in the new.html.erb doesn't hide?
What is the problem?
Thanks all for yours answers
If you are using jquery then you left the $ in front of the js script.
$("#test").hide();

Resources