Ruby on Rails POST request fails - ruby-on-rails

Here the thing goes, I wanna write a login in a page in Ruby on Rails, when the url is localhost:3000/admin, I'll get the page which need to fill in. After the form has filled in, I submit the button and the form should be admitted to the create action with post method, however it still works with get method and new action.
What happens to it?
Here is the routes.rb file:
Prefix Verb URI Pattern Controller#Action
new_admin_users GET /admin/users/new(.:format) admin/users#new
admin_users POST /admin/users(.:format) admin/users#create
admin GET /admin(.:format) admin/users#new
POST /admin(.:format) admin/users#create
posts_home GET /posts/home(.:format) redirect(301, /posts)
posts_about GET /posts/about(.:format) redirect(301, /about)
Then here is the new action
<form class="form-signin">
<h2 class="form-signin-heading">Please sign in</h2>
<%= form_for :user,url:admin_users_path do |f| %>
<p>
<%= f.label :name%><br>
<%= f.text_field :name ,class:"form-control" %>
</p>
<p>
<%= f.label :pass%><br>
<%= f.text_field :pass,class:"form-control" %>
</p>
<div class="checkbox">
<label>
<input type="checkbox" value="remember-me"> Remember me
</label>
</div>
<p>
<%= f.submit'Sign in', :class=>"btn btn-lg btn-primary btn-block" %>
</p>
<%= link_to 'Back', posts_path %>
<%end%>
</form>
Here is the routes.rb:
Rails.application.routes.draw do
namespace :admin do
resources :users
get "", to:"users#new"
post "", to:"users#create"
end
get "/posts/home", to: redirect("/posts")
get "/posts/about", to: redirect("/about")
resources :posts do
resources :comments
end
root "posts#index"
get "/home",to: "posts#index"
get "/about",to: "posts#about"
end
If you have some throught, please tell me, thanks in advance!

You must have the actual User object built inside your controller. Try using that inside your form instead of symbol :user.
<%= form_for #user, url: admin_users_path do |f| %>
...

You can try explicitly specifying the method post
Instead of
<%= form_for :user,url:admin_users_path do |f| %>
Use this:
<%= form_for :user,url:admin_users_path, method: :post do |f| %>
Also check the created action in form created such way
Hope this Helps

Related

remove subdomain from form

I'm using a constraint to set a subdomain for pages in my app
get '/', to: 'referal#new', constraints: { subdomain: 'keystrategy' }
It brings me to keystrategy.[mypage]. This page only contains a few lines :
<%= form_for #referal, url: {action: "create", subdomain: false} do |f| %>
<%= f.text_field :referer %>
<input type="hidden" value="keystrategy">
<%= f.submit "Valider" %>
<% end %>
But when I try to load this page, I get the following error :
No route matches {:action=>"create", :controller=>"referal", :subdomain=>"keystrategy"}
What am I missing ? I thought the subdomain: false would prevent this
use this code:
<%= form_for #referal, url: referal_url(subdomain: false) do |f| %>
<%= f.text_field :referer %>
<input type="hidden" value="keystrategy">
<%= f.submit "Valider" %>
<% end %>
Ok, so I found out it was not about the form itself, but rather because of routing. When using a subdomain, every new route generated by
resources :whatever
assumes you're doing so in your current subdomain. Therefore, if subdomain.yousite.com points to a view including a form, the form will be handled by subdomain.yoursite.com/whatevers, as a POST request.
So, you have to make sure that this route includes your subdomain. In your routes.rb file, add these lines:
get '/', to: 'whatever#new', constraints: { subdomain: 'yoursubdomain' }
post '/whatevers', to: 'whatever#create', constraints: { subdomain: 'yoursubdomain' }
Your form should look like this :
<%= form_for #referal do |f| %>
<%= f.text_field :referer %>
<input name="referal-type" type="hidden" value="keystrategy">
<%= f.submit "Valider" %>
<% end %>
And you're all set.

undefined method user_path' form_for

I have a UsersController and it has below code
def sign_up
#user = User.new
end
And my view page has
<div class="col-md-6 col-md-offset-3">
<%= form_for #user do |f| %>
<%= f.label :first_name%>
<%= f.text_field :first_name %>
<%= f.label :last_name %>
<%= f.text_field :last_name %>
<%= f.submit "Register", class: 'btn btn-primary'%>
<% end %>
</div>
My routes.rb file contains the following entry
get 'signup' => 'users#sign_up'
But When I submit the form, it says
ActionView::Template::Error (undefined method `users_path' for #<#<Class:0x00000004d91490>:0x00000004d90220>)
Why does this throw an error and do I need to explicity point to url in the form_for?? Why is it so??
Change your routes to:
resources :users, only: [:new, :create], path_names: {new: 'sign_up'}
and rename your sign_up action back to new. The reason you are getting the error is rails trying to guess the correct url for given resource. Since you have passed #user, which is an instance of User class, it will try to call "#{#user.class.model_name.route_key}_path key, which results in the error you got.
To solve the issue you need either make your routes to define users_path or you need to specify the url directly using url option. users_path can be defined by either index or create action, so the above solution will work (and will not create remaining CRUD routes, yey!)
Try changing this line:
<%= form_for #user do |f| %>
to this:
<%= form_for(#user, url: 'signup') do |f| %>

can't direct manual login away from sessions#create

Running Ruby 1.9.3p545 rails 4.1.4
I have an application where users canlogin through facebook, twitter, etc and can rehister manually. I would like a logon process for those who have registered manually.
Routes are
get 'auth/:provider/callback', to: 'sessions#create'
get 'auth/failure', to: redirect('/')
get 'signout', to: 'sessions#destroy', as: 'signout'
get "sign_up" => "profiles#new", :as => "sign_up"
get "log_in" => "logins#new"
post "log_in" => "logins#login"
Everything works fine except the manual logi. logins.new presents a form ok bu the subsequent submit always ends up in sessions controller at create.
I defined a login controller and tried to use the above post in the routes to get it away from the omniauth process in sessions#create.
The login form is
Log in
<%= form_tag sessions_path do %>
<p>
<%= label_tag :email %><br />
<%= text_field_tag :email, params[:email] %>
</p>
<p>
<%= label_tag :password %><br />
<%= password_field_tag :password %>
</p>
<p class="button">
<%= submit_tag "Sign in" %>
</p>
<% end %>
logins#login is
def login
authorized_user = Profile.authenticate(params[:name_or_email],params[:password])
if authorized_user
flash[:notice] = "Wow Welcome again, you logged in as #{authorized_user.username}"
redirect_to(:action => 'home')
else
flash[:notice] = "Invalid Username or Password"
flash[:color]= "invalid"
render "login"
end
Is tehre any way I can direct the submit of the login form away from the sessions controller?
Thanks in advance
end
The line
<%= form_tag sessions_path do %>
is what's throwing things off. It makes the form post to sessions_path. Try replacing it with <%= form_tag log_in_path do %>, or, better, yet, replace it with <%= form_tag "" do %> since the default is to post to the same URL as the current page.
Some more clarification:
<%= form_tag sessions_path do %>
generates the following HTML (roughly, skipping some details that aren't relevant to this issue):
<form action="/sessions" method="post">
since /sessions is the path to sessions#create. You want the action to be /log_in, i.e. the path to logins#login, so you want to change the argument you're passing to form_tag.
Since you're already on the page log_in, if you leave the action blank, i.e.:
<form method="post">
it will get you where you want, since the default behavior of the browser is to post to the same page.

How do you update a nested has_one resource?

I seem to have two problems
1) While trying to update my singular nested resource
Restaurant has_one Hour
and
Hour belongs_to Restaurant
resources :restaurants do
resource :hour
end
with an edit link on my restaurant show page called:
<%= link_to 'Set Hour', edit_restaurant_hour_path([#restaurant, #restaurant.hour]) %>
and the edit page has a partial render that looks like:
<%= render :partial => 'restaurants/hours', :locals => { :hour => 'hour' } %>
which loads a partial named _hours.html.erb:
<%= form_for hour do |f| %>
<div class="row-fluid">
<div class="span1 hours_input">
<h3>Monday</h1>
From
<%= f.text_field :from_monday, :class => 'span20 hour_field' %>
To
<%= f.text_field :to_monday, :class => 'span20 hour_field' %>
</div>
<div class="span1 hours_input">
<h3>Tuesday</h3>
From
<%= f.text_field :from_tuesday, :class => 'span20 hour_field' %>
To
<%= f.text_field :to_tuesday, :class => 'span20 hour_field' %>
</div>
<div class="span1">
<%= f.submit 'Set Hours' %>
</div>
</div>
but once I press the submit button it gives me the error:
No route matches [POST] "/restaurants/34/hour/edit"
I tried setting it as:
<%= form_for hour, :method => put, :html => { :action => 'update' } do |f| %>
but with no luck.
Any help would be greatly appreciated!
I'm using rails 3.2.3
2) My second problem is rather mysterious.
Once I press on the button
<%= link_to 'Set Hour', edit_restaurant_hour_path([#restaurant, #restaurant.hour]) %>
on the restaurant show page, it'll give the url:
http://localhost:3000/restaurants/34//hour/edit
with the double slash before //hour. I suspect this will break in production but doesn't seem to affect me in development.
Again, thanks for reading and have a good one!
Edit: Here's the rake routes--
restaurant_hour POST /restaurants/:restaurant_id/hour(.:format) hours#create
new_restaurant_hour GET /restaurants/:restaurant_id/hour/new(.:format) hours#new
edit_restaurant_hour GET /restaurants/:restaurant_id/hour/edit(.:format) hours#edit
GET /restaurants/:restaurant_id/hour(.:format) hours#show
PUT /restaurants/:restaurant_id/hour(.:format) hours#update
DELETE /restaurants/:restaurant_id/hour(.:format) hours#destroy
restaurants GET /restaurants(.:format) restaurants#index
POST /restaurants(.:format) restaurants#create
new_restaurant GET /restaurants/new(.:format) restaurants#new
edit_restaurant GET /restaurants/:id/edit(.:format) restaurants#edit
restaurant GET /restaurants/:id(.:format) restaurants#show
PUT /restaurants/:id(.:format) restaurants#update
DELETE /restaurants/:id(.:format) restaurants#destroy
hour GET /:restaurant/hour(.:format) hours#show
POST /:restaurant/hour(.:format) hours#create
hour_add GET /:restaurant/hour/add(.:format) hours#new
hour_edit GET /:restaurant/hour/edit(.:format) hours#edit
I figured it out, but it's apparently not the RESTful way to do it.
I just had to add:
<%= form_for hour, :url => { :action => "update" }, :html => { :method => 'put' } do |f| %>
and specify the action/method for the update to work.
Another post suggested that just using:
<%= form_for #hour do |f| %>
would have worked, too, but I wasn't having any luck with that for some reason.

Rails 2.3.11 RESTful route not calling create action from form

I have a controller called "Notes", and its associated model is Note, with a text field called "note" (I know).
I have a very simple form in the new.html.erb view:
<% form_for(#note) do |f| %>
<p><%= f.error_messages %> </p>
<h2 class="productList"><label for="">Note: </label>
<%= f.text_area :note, :cols => "50", :rows => "10" %></h2>
<br />
<p><%= f.submit "Create" %></p>
<% end %>
However, upon clicking the "Submit" button, the action being called is from a completely different controller:
Processing OtherController#add_note (for 127.0.0.1 at 2012-07-30 09:04:42) [POST]
Please note that this action is not even defined in routes.rb, though the controller is set up as a resource.
My "notes" line in routes.rb looks like this:
map.resources :notes, :collection => { :note_list => :get, :get_json_list => :get }, :member => { :applications => :get, :replace => :get }
And "rake routes" yields these lines for the controller:
get_json_list_notes GET /notes/get_json_list(.:format) {:controller=>"notes", :action=>"get_json_list"}
note_list_notes GET /notes/note_list(.:format) {:controller=>"notes", :action=>"note_list"}
notes GET /notes(.:format) {:controller=>"notes", :action=>"index"}
POST /notes(.:format) {:controller=>"notes", :action=>"create"}
new_note GET /notes/new(.:format) {:controller=>"notes", :action=>"new"}
edit_note GET /notes/:id/edit(.:format) {:controller=>"notes", :action=>"edit"}
replace_note GET /notes/:id/replace(.:format) {:controller=>"notes", :action=>"replace"}
applications_note GET /notes/:id/applications(.:format) {:controller=>"notes", :action=>"applications"}
note GET /notes/:id(.:format) {:controller=>"notes", :action=>"show"}
PUT /notes/:id(.:format) {:controller=>"notes", :action=>"update"}
DELETE /notes/:id(.:format) {:controller=>"notes", :action=>"destroy"}
I don't have anything bound to the form or controls in my Javascript either. What would make it call the wrong controller and action?
UPDATE - Here is the output of the form_for tag:
<form id="new_note" class="new_note" method="post" action="/notes">
<p> </p>
<h2 class="productList">
<label for="">Note: </label>
<textarea id="note_text" rows="10" name="note_text" cols="50"></textarea>
</h2>
<br>
<p>
<input id="note_submit" type="submit" value="Create" name="commit">
</p>
</form>
UPDATE 2 - Form is being passed "Note.new"
I'm a freaking idiot. I have a Javascript listener bound to "note_submit" on another page.

Resources