I am stuck with persisting data on button click. Is it possible to get the parameters to different controller function from another page.
Controller
def create
#login=Login.new
#login.name=params[:name]
#login.email=params[:email]
#login.password=params[:password]
#login.phone_number=params[:phone_number]
if #login.save
render :action => 'success'
else
puts (#login.errors.full_messages)
render :action => 'failure'
end
end
def operation
if params[:commit] == "Clicked"
puts ("Inside CLICKED")
redirect_to action: 'clicked'
else
redirect_to action: 'create'
end
end
view (create.html.erb)
<h1>Welcome to DemoSite.com</h1>
<p></p>
<%= form_for (#login), :url => {:action => "create"} do |f| %>
<p>
<%= f.label :Name %><br>
<%= f.text_field :name %>
</p>
<p>
<%= f.label :Email %><br>
<%= f.text_field :email %>
</p>
<p>
<%= f.label :Phone_Number %><br>
<%= f.telephone_field :phone_number %>
</p>
<p>
<%= f.label :Password %><br>
<%= f.password_field :password %>
</p>
<p>
<%= f.label :password_confirmation %><br>
<%= f.password_field :password_confirmation %>
</p>
<p>
<%= f.submit('Submit') %>
</p>
<% end %>
index.html.erb
<h1>Welcome to DemoSite.com</h1>
<p></p>
<%= form_tag "/logins/operation", :method => "post" do %>
<p>
<%= label_tag(:username, "Username") %><br>
<%= text_field_tag(:username) %>
</p>
<p>
<%= label_tag(:password, "Password") %><br>
<%= password_field_tag(:password) %>
</p>
<p>
<%=submit_tag "Create" %>
<%= submit_tag "Clicked" %>
</p>
When I run this, it directs me to failure.html.erb directly from index.html.erb when I click create button, without hitting the create.html.erb. Also, how can I persist the data inside create method after button click?
Your operation action redirects to create and your create action either renders failure or succes, your create action never does the default thing (namely rendering your create-view).
Most of the times the new action renders the form, and the create action (which should be POST) actually creates (saves) the data.
The redirect to create as you do it now, will never succeed, because it will not receive any data, so it will always fail to create the user, so it will always show the failure screen.
[UPDATE] simplest (but still dirty way) to fix it :
If you redirect to your create action, it is a GET request, not POST.
So the simplest fix is this:
def create
if request.post?
#login = Login.new(params)
if #login.save
render :action => 'success'
else
puts (#login.errors.full_messages)
render :action => 'failure'
end
else
#login = Login.new
end
end
So if it is a POST: try to save and check the errors. If it is a GET just render the create.html.erb.
The best, clean REST way, is to redirect to the new action from your operation action, and your form will POST to the create action. This is how it is supposed to be.
Related
I am trying out for basic login and registration in ruby on rails,
ISSUE: When I click register button from new.html I am getting GET request but I can see method="post" in page source of that html
I have posted my code below
new.html.erb
<form>
<%= form_for(#user) do |f| %>
<%= f.label :user_name %>
<%= f.text_field :user_name %></br>
<%= f.label :email_id %>
<%= f.text_field :email_id %></br>
<%= f.label :password %>
<%= f.password_field :password %></br>
<%= f.label :college %>
<%= f.text_field :college %></br>
<%= f.label :major %>
<%= f.text_field :major %></br>
<%= f.label :current_job %>
<%= f.text_field :current_job %></br>
<%= f.submit("Create Account",class: "btn btn-primary") %>
<% end %>
</form>
My index.html.erb code which is loaded while application starts
<div class="container">
<div class="row">
<div class="login">
<%= form_tag("/user/login",:method => :post) do %>
<%= label_tag(:EmailId) %>
<%= text_field_tag(:email, params[:email]) %></br>
<%= label_tag(:password) %>
<%= password_field_tag(:password, params[:password]) %></br>
<%= submit_tag("Log In",class: "btn btn-primary") %>
<%= submit_tag("Register",class: "btn btn-primary") %>
<% end %>
</div>
</div>
</div>
My controller code
class UsersController < ApplicationController
def index
#user = User.all
end
def login
print "In Sign in controller"
#user = User.new
if params[:commit] == 'Register'
print "inside Register class"
redirect_to '/users/new'
else
#user = User.find(params[:email_id])
if #user and user.authenticate(params[:password])
sessions[:userId] = #user.user_id
end
end
end
def new
puts "****Inside New Method******"
#user = User.new
end
def create
puts "****Inside create Method******"
end
private
def user_params
end
end
My Route code
Rails.application.routes.draw do
root 'users#index'
resources :users
post '/users/login' => 'users#login'
As per my understanding post request should hit create method, but get /users method is hitting. Please help me out regarding this
Why do you have nested forms in new.html.erb? Remove the first form tag
<form>
<%= form_for(#user) do |f| %>
You have a form tag inside another form tag. Remove the tag at the top of your form. <%= form_for(#user) %> takes care everything that's needed to build the correct form.
I have this HTML:
<% provide(:contact, "active") %>
<% provide(:title, "Contacto | Recotiendame") %>
<div align="center">
<h1 id_"page_title">Contactanos!</h1>
<div class="skinny_wrapper wrapper_padding"
<%= form_for contact_path, url: #done do |f| %>
<%= f.label :Nombre %><br>
<%= f.text_field :Nombre, required: true %>
<br>
<%= f.label :Email %><br>
<%= f.email_field :Email, required: true %>
<br>
<%= f.label :Mensaje %><br>
<%= f.text_area :Mensaje, as: :text %>
<div class= "hidden">
<%= f.label :nickname %><br>
<%= f.text_field :nickname, hint: 'dejalo en blanco' %>
</div>
<br>
<%= f.submit 'Enviar Mensaje', class: "button" %>
</div>
<% end %>
</div>
with this controller:
class ContactController < ApplicationController
def new
#contact = Contact.new
end
def create
#contact = Contact.new(params[:contact])
#contact.request = request
if #contact.deliver
flash.now[:notice] = 'Gracias por su mensaje. Lo contactaremos luego!'
else
flash.now[:error] = 'No se pudo enviar el mensaje.'
render :new
end
end
end
The problem is that the submit button does nothing. How can I make it work to redirect me to create? I have seen lots of answers to this question but none works for me.
EDIT 1
When I did #done, it was only to try things.
If I had to guess, I think you've got your form_for fields wrong. Normally you'd have something like: form_for #contact and it'd Just Work, but if you wanted to override the default url, you'd pass a different url eg
form_for #contact, url: contacts_path`
(note the plural is important).
I don't know what #done is meant to be... but it probably shouldn't be there... and putting the contact_path has two incorrect things about it:
1) you shouldn't have a url at that point, but an object (in this case the object is the contact)
2) contact_path is for showing a single contact that has already been saved, for creating a new contact, you need contacts_path (the idea is that you're posting a new contact to the set of contacts).
I am a beginner in rails, and I'm having an issue in a registration form.
I have users and emails in different tables (take a look) but the user registration form has an email field mixed with all the other fields such as username and password.
At first render there's no issue, but when trying to save, if any error occurs (such as duplicated username or email) I follow steps here, where it says (don't redirect_to, just do render 'new' to keep previously inserted info. That's when it throws an error saying email is not known.
I don't want to create the field email in the users table, since I already removed it from the original model. How do I fix that?
Form code
<%= form_for :user, url: users_path do |f| %>
<p>
<%= f.label :username %>
<%= f.text_field :username %>
</p>
<p>
<%= f.label :name %>
<%= f.text_field :name %>
</p>
<p>
<%= f.label :email %>
<%= f.email_field :email # Error is thrown in this line %>
</p>
<p>
<%= f.label :password %>
<%= f.password_field :password %>
</p>
<p>
<%= f.label :password_confirmation %>
<%= f.password_field :password_confirmation %>
</p>
<p>
<%= f.submit %>
</p>
Controller code
def create
# render plain: params[:user].inspect
#user = User.new(user_registration_params)
if #user.save
email_params = {email: params[:user][:email], primary: true}
#email = Email.new(email_params)
#email.user = #user
if #email.save
redirect_to #user
else
#user.destroy
end
else
render 'new'
end
end
If you have connected the both models via belongs_to you can set up your form to update/create both models.
You have to declare you user with accepts_nested_attributes_for.
See a full example here:
http://railscasts.com/episodes/196-nested-model-form-part-1
I have the following simple rails page:
<h1> New User </h1>
<%= form_for :user, url:users_path do |f| %>
<p>
<%= f.label :email %>
<%= f.text_field :email %>
</p>
<p>
<%= f.label :password %>
<%= f.text_field :password %>
</p>
<%= f.submit %>
<% end %>
The create action gets executed and I want to access the :email attribute.
def create
render text: params[:email].inspect
end
The above always displays nil.
form_for :user will place all parameters beneath a :user key
render text: params[:user][:email].inspect
I've been trying to create an order confirmation page for my rails app, and am not quite sure how to go about it in a restful way.
There were a few answers on this question that got me halfway there, but the problem was that I wasn't quite sure how to set up the form in the rails view so that it would take the user to a confirmation page with all their details instead of a create action.
Right now my view is simple:
<% form_for :order do |f| %>
<%= f.error_messages %>
<p>
<%= f.label :first_name %><br />
<%= f.text_field :first_name, :size => 15 %>
</p>
<p>
<%= f.label :last_name %><br />
<%= f.text_field :last_name, :size => 15 %>
</p>
(Be sure to enter your name as it appears on your card)
<p>
<%= f.label :card_type %><br />
<%= f.select :card_type, [["Visa", "visa"], ["MasterCard", "master"], ["Discover", "discover"], ["American Express", "american_express"]] %>
</p>
<p>
<%= f.label :card_number %><br />
<%= f.text_field :card_number %>
</p>
<p>
<%= f.label :card_verification, "Card Verification Value (CVV)" %><br />
<%= f.text_field :card_verification, :size => 3 %>
</p>
<p>
<%= f.label :card_expires_on %><br />
<%= f.date_select :card_expires_on, :discard_day => true, :start_year => Date.today.year, :end_year => (Date.today.year+10), :add_month_numbers => true %>
</p>
<p><%= f.submit "Submit" %></p>
What things should I be doing to direct the user to a confirmation page that shows all the order details?
Thanks!
Kenji
There were a few answers on this
question that got me halfway there,
but the problem was that I wasn't
quite sure how to set up the form in
the rails view so that it would take
the user to a confirmation page with
all their details instead of a create
action.
Directing a form to a non standard page is pretty simple.
Add a url option form_for.
Such that
<% form_for :order do |f| %>
becomes
<% form_for :order :url => {:action => "confirm"} do |f| %>
You'll need to crate the confirm action in your routes, but that only involves this:
map.resources :orders, :collection => {:confirm => :get}
All you need now is a basic controller action and a view:
def confirm
#order = Order.new(params[:order])
unless #order.valid?
render :action => :new
else
end
end
Your view should look almost identical to the show view, with the addition of a form submitting #order to the create action.
Why don't you pull the confirmation via ajax for example, pull the result and put it as an overlay div, upon confirmation submit the original values in the form.
If you still need to do it your way then check wizardly, it's exactly designed for such uses.
I would like to update the answer for more elegant Rails 4 or up.
I hope it will help newbies like me. Ruby is awesome! :)
routes.rb
resources :orders do
collection do
post 'confirm'
end
end
orders_controller.rb
def confirm
#order = Order.new(order_params) # GET THE POST parameters
render :new if #order.invalid? # Return if false
end
form.html.erb
<%= form_for #order, url: {action: 'confirm'} do |f| %>