No Route Error but have the route in rake routes - ruby-on-rails-3.1

Here is my routes file:
devise_for :users, :controllers => { :omniauth_callbacks => "users/omniauth_callbacks" }
resources :users do
post 'update_and_sign_in', :on => :member
end
Here is the output from rake routes:
update_and_sign_in_user POST /users/:id/update_and_sign_in(.:format) users#update_and_sign_in
users GET /users(.:format) users#index
POST /users(.:format) users#create
new_user GET /users/new(.:format) users#new
edit_user GET /users/:id/edit(.:format) users#edit
user GET /users/:id(.:format) users#show
PUT /users/:id(.:format) users#update
DELETE /users/:id(.:format) users#destroy
Here is the controller:
def update_and_sign_in
#user = User.find(params[:id])
if #user.update_attributes(params[:user])
redirect_to root_path, :notice => "You have successfully signed up"
else
render 'get_email'
end
end
Here is the form:
=form_for(#user,:url => update_and_sign_in_user,:method => "put", :html => {:class => 'well'}) do |f|
I get this error and I can't figure out why or how to fix it:
No route matches {:action=>"update_and_sign_in", :controller=>"users"}

Your route is a POST but your method in the form is PUT.

Just to clarify: Which controller is :
def update_and_sign_in
#user = User.find(params[:id])
if #user.update_attributes(params[:user])
redirect_to root_path, :notice => "You have successfully signed up"
else
render 'get_email'
end
end
on? UsersController or Users::OmniauthCallbacksController ?

Related

rails redirect_to error No route matches

I'm trying to redirect to login page or root page
redirect_to new_user_session_path, :alert => exception.message
redirect_to root_path, :alert => exception.message
but both are returning an error
No route matches {:action=>"new", :controller=>"devise/sessions"}
No route matches {:action=>"index", :controller=>"home"}
when I do the rake routes there is a root path and a new_user_session (made with devise)
the routes.rb has
devise_for :users, :path => '', :path_names => {:sign_in => 'login', :sign_out => 'logout'}
root 'home#index'
If I do a
redirect_to '/', :alert => exception.message
it works and goes to the home#index, but if I try with
redirect_to '/login', :alert => exception.message
then it says localhost not working, localhost redirected too much times
The redirection is in the application_controller.rb inside a catch exception for denied access in cancan
rescue_from CanCan::AccessDenied do |exception|
redirect_to '/', :alert => exception.message
end
Edit: Solution
if I write main_app. before the path it works so main_app.new_user_session_path and main_app.root_path works fine.
I've always done it without the main_app and it used to work, I'm not sure why now I need the main_app before the path, but it works.

How to set cookies in Ruby on Rails 3?

I want to store username and password in cookies.If due to some reason my page removed when i will type the URL and press enter the page will come which should come after login.I have used also session.Please help me to add cookies in my app.
I am working on the below code.
class SessionsController < ApplicationController
def loginuser
#users=User.authenticate(params[:users][:email], params[:users][:password])
if #users
session[:user_id]=#users.id
flash[:notice]="login successfull"
flash[:color]="valid"
redirect_to :action => 'member',:controller => 'homes'
else
flash[:notice]="could not Logged in"
flash[:color]="invalid"
render 'member', :controller => 'homes'
end
end
def removeuser
session[:user_id] = nil
flash[:notice]="user logged out successfully"
flash[:color]="valid"
redirect_to :action => 'member', :controller => 'homes'
end
end
Please help me to add cookies.
Just as you are using session object to maintain session details, in the same way use cookies object to set cookies.
Here:
cookies[:user_name] = "david"
# Cookies are read and written through ActionController#cookies.
Also follow this reference: http://api.rubyonrails.org/classes/ActionDispatch/Cookies.html
Example:
def loginuser
#users=User.authenticate(params[:users][:email], params[:users][:password])
if #users
session[:user_id] = #users.id
cookies[:user_id] = #users.id # setting cookies
flash[:notice]="login successfull"
flash[:color]="valid"
redirect_to :action => 'member',:controller => 'homes'
else
flash[:notice]="could not Logged in"
flash[:color]="invalid"
render 'member', :controller => 'homes'
end
end

Friendly_Id record not found

I get a record not found exception using friendly_id 5.0 stable with Rails 4.0
Error:
Migration:
class AddSlugToUsers < ActiveRecord::Migration
def change
add_column :users, :slug, :string
add_index :users, :slug
end
end
Controller:
class UsersController < ApplicationController
load_and_authorize_resource
before_filter :authenticate_user!
def index
authorize! :index, #user, :message => 'Not authorized as an administrator.'
#users = User.all
end
def show
##user = User.find(params[:id])
#user = User.friendly.find(params[:id])
end
def update
authorize! :update, #user, :message => 'Not authorized as an administrator.'
#user = User.find(params[:id])
if #user.update_attributes(params[:user], :as => :admin)
redirect_to users_path, :notice => "User updated."
else
redirect_to users_path, :alert => "Unable to update user."
end
end
def destroy
authorize! :destroy, #user, :message => 'Not authorized as an administrator.'
user = User.find(params[:id])
unless user == current_user
user.destroy
redirect_to users_path, :notice => "User deleted."
else
redirect_to users_path, :notice => "Can't delete yourself."
end
end
end
The Data:
INSERT INTO
users(id,email,encrypted_password,reset_password_token,reset_password_sent_at,remember_created_at,
sign_in_count,current_sign_in_at,last_sign_in_at,current_sign_in_ip,last_sign_in_ip,
created_at,updated_at,first_name,last_name,alias,bio,slug)
VALUES
(10,'me1#example.com','$2a$10$MYHASG','',null,null,0,null,null,'','',
Invalid Date,Invalid Date,'greek','god','tool','','tool');
It works if I put the ID into the url
http://0.0.0.0:3000/users/10
but does not work when using the slug
http://0.0.0.0:3000/users/tool
The quickest fix is to use the old 4-style finders as described in the readme by using the :finders addon.
Then you'll have friendly-id access via the "normal" find() method.
Example:
friendly_id :foo, use: [:slugged, :finders] # you can now do MyClass.find('bar')

Rails form validation works in one template but not another for the same Model

Another hair-puller. AFter two days of fighting with this I cannot figure out what is wrong here.
Basically I have a form validation triggered by the model:
validates :user, :presence => true, :uniqueness => true
validates :email, :presence => true, :uniqueness => true, :on => :create
validates :passwordHash, :presence => true, :confirmation => true, :on => :create
The user not being empty works on the update form View:
= simple_form_for #user do |f|
= f.input :user
= f.input :locale
= f.input :localeLanguage, :label => 'Language', :as => :select, :collection => $language_array
= f.input :moderator
= f.input :email
= f.input :passwordHash, :label => 'Password'
But not on the new users View:
= simple_form_for #user do |f|
%table.table-condensed
%tr
%td
=f.input :user, :label => false, :placeholder => 'username'
%tr
%td
= f.input :passwordHash, :label => false, :placeholder => 'password'
%tr
%td
= f.input :email, :label => false, :placeholder => 'email'
%tr
%td
= f.submit "Create User", :class => 'btn btn-primary'
The only difference I can see between these views is that the first one has sessions created since a user has already logged in, the second one doesn't. But as far as I know this should not make a difference. Of course, the update form does have an actual #user object whereas in the new one it is empty. But I've seen Ryan Bates' railscast of a new user validation and he does pretty much the same thing.
What happens is the users#create action being invoked after submitting the form with empty values (which should not be possible). Of course I get an error because the passwordHash is empty.
I should point out that I'm not using any extra gems to aid in password confirmation (in the railscast, Bates uses bcrypt but I can't use it because we create the password hash a different way plus I think that's for the password confirmation magic only). In any case this should not affect the form validation should it?
Any theories or ideas are welcome here, I'm going crazy. I'm about to write some crappy javascript to do it by hand which would be awful and would probably take me a week, I don't do javascript ;)
Thanks.
Edit
Per Rachid's request, here are the new and create actions:
def new
#user = User.new
end
def create
#failsafe for failing form validation
unless params[:passwordHash].present?
redirect_to new_user_path, :notice => 'User or password cannot be blank'
else
password_and_salt = User.hash_password(params[:passwordHash])
hashed_password = password_and_salt[:password]
user_salt = password_and_salt[:salt]
#user = User.new(:user => params[:user], :passwordHash => hashed_password, :salt => user_salt)
if #user.save
session[:user_id] = #user.id
redirect_to session[:item_to_edit]
else
redirect_to new_user_path, :notice => "User already exists, please pick another one"
end
end
end
Edit 2
I've rewritten the create method based on the first answer, but still getting an error:
def create
respond_to do |format|
if params[:passwordHash].present? && params[:user].present?
password_and_salt = User.hash_password(params[:passwordHash])
hashed_password = password_and_salt[:password]
user_salt = password_and_salt[:salt]
#user = User.new(:user => params[:user], :passwordHash => hashed_password, :salt => user_salt, :online_user => 1 )
if #user.save
session[:user_id] = #user.id
redirect_to session[:item_to_edit]
else
format.html { render :action => "new" }
format.json { render :json => #user.errors, :status => :unprocessable_entity }
end
else
format.html { render :action => "new" }
format.json { render :json => #user.errors, :status => :unprocessable_entity }
end
end
end
The error is undefined method 'model_name' for NilClass:Class for this line:
= simple_form_for #user do |f|
Obviously the #user = User.new is not making it back to the form. At this point I'm a little confused as to how I should write the create method for it to work properly and show the error messages. But I feel I'm closer :)
#misha, here is the update controller action, it's just pretty standard scaffolding:
def update
#user = User.find(params[:id])
respond_to do |format|
if #user.update_attributes(params[:user])
if session[:return_to]
format.html { redirect_to session[:return_to], :notice => 'User was successfully updated.' }
else
format.html { redirect_to users_path, :notice => 'User was successfully updated.' }
end
format.json { head :ok }
else
format.html { render :action => "edit" }
format.json { render :json => #user.errors, :status => :unprocessable_entity }
end
end
end
First of all what you assume here is incorrect:
What happens is the users#create action being invoked after submitting
the form with empty values (which should not be possible). Of course I
get an error because the passwordHash is empty.
It is possible that users#create is invoked and actually it should happen. It is in the create action where you handle this stuff. I think your problem is the fact that you do a redirect if the #user is not saved. You should render the view again, so the error messages can be displayed.
So instead of:
redirect_to new_user_path, :notice => "User already exists, please pick another one"
Try:
render :action => 'new'
Edit based on your comment:
When validation fails Rails populates #user.errors automatically. You don't have to do anything in the controller (i.e. your create action)! All you have to do is display the errors in #user.errors in your view.
About the error you are getting now:
The reason you are getting the error is that #user is not set. You have to rewrite your create method to something like this:
def create
respond_to do |format|
if params[:user][:passwordHash].present?
password_and_salt = User.hash_password(params[:user][:passwordHash])
hashed_password = password_and_salt[:password]
user_salt = password_and_salt[:salt]
end
#user = User.new(params[:user].merge({:passwordHash => hashed_password, :salt => user_salt, :online_user => 1}))
if #user.save
session[:user_id] = #user.id
redirect_to session[:item_to_edit]
else
format.html { render :action => "new" }
format.json { render :json => #user.errors, :status => :unprocessable_entity }
end
end
end

Undefined method 'title' for nil:NilClass

I am following railsspace book but when i trying edit show and eliminate a post owner (chapter 15) I get: error message
undefined method `title' for nil:NilClass
follow extact:
1: <div class="post">
2: <div class="post_title">
3:
4: <%= sanitize post.title %>
5: <% unless hide_edit_links? %>
6: <span style="float:right">
7: <%= link_to_unless_current 'Mostrar', blog_post_path(post.blog, post) %> |
Ruby 1.9.2
Rails 3.1.3
The controller, views and routes is as follow:
Controller: posts_controller
# Encoding: UTF-8
class PostsController < ApplicationController
helper :profile
before_filter :protect, :protect_blog
# GET /posts
# GET /posts.xml
def index
#Recheck implement paginate for Rails 3.1.3
##pages, #posts = paginate(#blog.posts)
#posts = #blog.posts
#title = "Administración del Blog"
respond_to do |format|
format.html # index.rhtml
format.xml { render :xml => #posts.to_xml }
end
end
# GET /posts/1
# GET /posts/1.xml
def show
#post = Post.find(params[:id])
#title = #post.title
respond_to do |format|
format.html # show.rhtml
format.xml { render :xml => #post.to_xml }
end
end
# GET /posts/new
def new
#post = Post.new
#title = "Nuevo post"
end
# GET /posts/1;edit
def edit
#post = Post.find(params[:id])
#title = "Edit #{#post.title}"
end
# POST /posts
# POST /posts.xml
def create
#post = Post.new(params[:post])
#post.blog = #blog
respond_to do |format|
if #post.duplicate? or #blog.posts << #post
flash[:notice] = 'Post was successfully created.'
format.html { redirect_to blog_post_url(:id => #post) }
format.xml { head :created, :location => blog_post_url(:id => #post) }
else
format.html { render :action => "new" }
format.xml { render :xml => #post.errors.to_xml }
end
end
end
# PUT /posts/1
# PUT /posts/1.xml
def update
#post = Post.find(params[:id])
respond_to do |format|
if #post.update_attributes(params[:post])
flash[:notice] = 'Post was successfully updated.'
format.html { redirect_to post_url(:id => #post) }
format.xml { head :ok }
else
format.html { render :action => "edit" }
format.xml { render :xml => #post.errors.to_xml }
end
end
end
# DELETE /posts/1
# DELETE /posts/1.xml
def destroy
#post = Post.find(params[:id])
#post.destroy
respond_to do |format|
format.html { redirect_to posts_url }
format.xml { head :ok }
end
end
private
# Ensure that user is blog owner, and create #blog.
def protect_blog
#blog = Blog.find(params[:blog_id])
user = User.find(session[:user_id])
unless #blog.user == user
flash[:notice] = "That isn't your blog!"
redirect_to hub_url
return false
end
end
end
View: index
<h2>Sus Blog Posts</h2>
<p class="edit_link">
<%= link_to 'Agregar nuevo post', new_blog_post_path %>
<%= "| Pages: #{pagination_links(#pages)}" if paginated? %>
</p>
<%= render :partial => "post", :collection => #posts %>
View: post
<div class="post">
<div class="post_title">
<%= sanitize post.title %>
<% unless hide_edit_links? %>
<span style="float:right">
<%= link_to_unless_current 'Mostrar', blog_post_path(post.blog, post) %> |
<%= link_to_unless_current 'Editar', edit_blog_post_path(post.blog, post) %> |
<%= link_to 'Eliminar', blog_post_path(post.blog, post),
:confirm => 'Deseas eliminar este post?', :method => :delete %>
</span>
<% end %>
</div>
<div class="post_body"><%= sanitize post.body %></div>
<div class="post_creation_date">
Publicado <%= time_ago_in_words post.created_at %> ago
<% if post.updated_at != post.created_at %>
<br /> Modified <%= time_ago_in_words post.updated_at %> ago
<% end %>
</div>
</div>
In this view , i has triying put # in the variable post =#post, but it not work
Routes
Expression::Application.routes.draw do
get "email/remind"
get "avatar/index"
get "avatar/upload"
get "avatar/delete"
get "community/index"
get "community/browse"
get "community/search"
get "faq/index"
get "faq/edit"
get "spec/index"
get "spec/edit"
get "profile/index"
get "profile/show"
get "user/index"
get "user/register"
get "site/index"
get "site/about"
get "site/help"
get "user/login"
get "user/logout"
get "user/edit"
get "user_mailer/welcome_email"
post "user/register"
post "user/login"
post "user/edit"
post "spec/edit"
post "faq/edit"
post "community/index"
post "community/search"
post "avatar/upload"
post "email/remind"
resources :blogs do
resources :posts
end
# The priority is based upon order of creation:
# first created -> highest priority.
# Sample of regular route:
# match 'products/:id' => 'catalog#view'
# Keep in mind you can assign values other than :controller and :action
# Sample of named route:
# match 'products/:id/purchase' => 'catalog#purchase', :as => :purchase
# This route can be invoked with purchase_url(:id => product.id)
# Sample resource route (maps HTTP verbs to controller actions automatically):
# resources :products
# Sample resource route with options:
# resources :products do
# member do
# get 'short'
# post 'toggle'
# end
#
# collection do
# get 'sold'
# end
# end
# Sample resource route with sub-resources:
# resources :products do
# resources :comments, :sales
# resource :seller
# end
# Sample resource route with more complex sub-resources
# resources :products do
# resources :comments
# resources :sales do
# get 'recent', :on => :collection
# end
# end
# Sample resource route within a namespace:
# namespace :admin do
# # Directs /admin/products/* to Admin::ProductsController
# # (app/controllers/admin/products_controller.rb)
# resources :products
# end
# You can have the root of your site routed with "root"
# just remember to delete public/index.html.
# root :to => 'welcome#index'
root :to => 'site#index'
# match'', :controller => 'site', :action => 'index', :id => nil
resources :user
match '/register', :to => 'user#register'
match '/about', :to => 'user#about'
match '/help', :to => 'user#help'
match '/login', :to =>'user#login'
match '/edit', :to =>'user#edit'
match '/user/welcome_email', :to => 'user#create'
#resources :profile
#match '/show', :to => 'profile#show'
# Install the default route as the lowest priority.
match ':controller/:action/:id'
match 'profile', :to => 'profile#show', :as => "profile"
match 'hub', :to => 'user#index', :as => 'hub'
##Change Route pagina 343
# You can have the root of your site routed by hooking up ''
# -- just remember to delete public/index.html.
match '', :controller => 'site', :action => 'index', :id => nil
###
#match'', :controller => 'user', :action => 'about', :id => nil
#match'', :controller => 'user', :action => 'help', :id => nil
# See how all your routes lay out with "rake routes"
# This is a legacy wild controller route that's not recommended for RESTful applications.
# Note: This route will make all actions in every controller accessible via GET requests.
# match ':controller(/:action(/:id(.:format)))'
end
ApplicationStacktrace
app/views/posts/_post.erb:4:in `_app_views_posts__post_erb__1793130860277527745_40556500'
app/views/posts/show.html.erb:3:in `_app_views_posts_show_html_erb__2356198700875868089_40643800'
app/controllers/posts_controller.rb:23:in `show
Use #post.title, instead of post.title on line 4 of your template.
After deleting your code is trying to redirect to posts_url.
However I do not see that in your routes. btw you can also do rake routes at the command line to see what your routes are.
I think you need to add a get for posts/index although I would really look to try and use RESTful routing which would clean up much of your routes.

Resources