Rails 3: Strange devise redirect error - ruby-on-rails

So, I got an interesting problem. I am attempting to override and redirect a devise sign_up and sign_in request to their appropriate profile pages but I am running into an error. The profiles and URL work by accessing it with console, link_to or by typing it out. For some reason the devise method won't route to it. I'm not sure why. Anyways, upvotes for all that contribute or solve. Thanks!
Routes:
root :to => 'pages#index'
get "pages/index"
devise_for :users, :path => 'accounts', :controllers => { :registrations => "registrations" }
get 'users/:id/profile' => 'profiles#show', :as => 'current_profile'
get 'users/:id/profile/edit' => 'profiles#edit', :as => 'edit_current_profile'
put 'users/:id/profile' => 'profiles#update'
resources :users do
resources :profiles
end
Registration Controller:
class RegistrationsController < Devise::RegistrationsController
protected
def after_sign_up_path_for(resource)
edit_current_profile_path(resource)
end
def after_sign_in_path_for(resource)
current_profile_path(resource)
end
end
Profile Controller
def show
#user = current_user
#profile = #user.profile
respond_to do |format|
format.html
end
end
Error message:
Routing Error
No route matches {:controller=>"profiles", :action=>"show"}
Try running rake routes for more information on available routes.
View: edit.html.erb
<%= form_for([#profile.user, #profile]) do |f| %>
<% if #profile.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#profile.errors.count, "error") %> prohibited this profile from being saved:</h2>
<ul>
<% #profile.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= f.label :real_name %><br />
<%= f.text_field :real_name %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>

You should give an attribute to your route helpers. Try it out
def after_sign_up_path_for(resource)
edit_current_profile_path(resource)
end
def after_sign_in_path_for(resource)
current_profile_path(resource)
end

Related

No route matches {:action=>"show", :controller=>"events", :id=>nil}, missing required keys: [:id]

How can I solve this error No route matches {:action=>"show", :controller=>"events", :id=>nil}, missing required keys: [:id]. When I click submit at form to create event rails show me this error.
My routes
Rails.application.routes.draw do
devise_for :users, controllers: {registrations: 'registrations'}
devise_scope :user do
get 'logout', to: 'user_sessions#destroy'
end
resources :topics do
member do
put 'vote' => "topics#vote"
get 'refresh_statistic' => "topics#refresh_statistic"
end
end
resources :subtopics do
member do
put 'vote' => "subtopics#vote"
get 'refresh_statistic' => "subtopics#refresh_statistic"
end
end
root :to => "topics#show"
resources :comments do
member do
put "like" => "comments#like"
end
end
resources :events
resources :users do
collection do
get 'update_password'
end
end
end
Form to add new event
<%= form_for #event do |f| %>
<div class="field">
<%= f.label :title %>
<%= f.text_field :title %>
</div>
<div class="field">
<%= f.label :content %>
<%= f.text_field :content %>
</div>
<div class="selector">
<%= f.label 'Owner type' %>
<%= f.select :owner_type, options_for_select([['Topic','Topic'], ['Subtopic', 'Subtopic']]) %>
<%= f.label 'Owner id' %>
<% if params[:owner_type] == 'Topic' %>
<%= f.collection_select(:owner_id, Topic.all, :id, :name, selected: (params[:owner_id ])) %>
<% else %>
<%= f.collection_select(:owner_id, Subtopic.all, :id, :name, selected: (params[:owner_id])) %>
<% end %>
</div>
<%= f.submit(#event) %>
<% end %>
Event controller
class EventsController < ApplicationController
before_action :set_event, only: %i[show edit update create]
def new
#event = Event.new
end
def create
#event = Event.new(create_params)
redirect_to event_path(#event)
end
def update
if #event.update_attributes(update_params)
redirect_to event_path(#event)
else
render :edit
end
end
def show
end
def index
#events = Event.all
end
private
def set_event
#event = Event.find_by_id(params[:id])
end
end
Rails show error at create action, redirect_to event_path(#event) line. Help me if possible, I'm at a time with this problem. Thanks.
Your create action needs to call #save on the new #event in a similar pattern to your update action.
It would be like:
def create
#event = Event.new(create_params)
if #event.save
redirect_to event_path(#event)
else
render :new
end
end

Devise routing error while using multiple models - RAILS 4.2.0

Actually I am using two models for my app that is User and Admin and I followed every steps to be dealt while using devise gem.
And I would like to have multiple login. When User logged in, must be redirected to respective profile and when Admin logged in, must be redirected to his respective profile.
I don't know where I am making mistake.
home/index.html.erb
<ul>
<li>User:<%= link_to 'User', new_user_session_path, target: "_blank" %></li>
<li>Admin:<%= link_to 'Admin', new_admin_session_path, target: "_blank" %></li>
</ul>
When I go to User link it gives me routing error which is as below;
And When I go to Admin link it gives me routing error which is as below;
routes.rb
Rails.application.routes.draw do
root "home#index"
devise_for :users, controllers: {
sessions: 'users/sessions',
registrations: 'users/registrations'
}
devise_scope :user do
authenticated do
root to: 'aslani#index', as: 'authenticated_user_root'
end
unauthenticated do
root to: 'aslani#index', as: 'unauthenticated_user_root'
end
end
devise_for :admins, controllers: {
sessions: 'admins/sessions',
registrations: 'admins/registrations'
}
devise_scope :admin do
authenticated do
root to: 'yaseen#index', as: 'authenticated_admin_root'
end
unauthenticated do
root to: 'yaseen#index', as: 'unauthenticated_admin_root'
end
end
end
aslani/index.html.erb
<% if user_signed_in? %>
I am Aslani.
<%= link_to 'Log out', destroy_user_session_path, method: :delete %>
<% else %>
<%= link_to 'Log In', new_user_session_path %>
<%= link_to 'Sign Up', new_user_registration_path %>
<% end %>
kola/index.html.erb
<% if admin_signed_in? %>
I am Kola.
<%= link_to 'Log out', destroy_admin_session_path, method: :delete %>
<% else %>
<%= link_to 'Log In', new_admin_session_path %></li>
<%= link_to 'Sign Up', new_admin_registration_path %>
<% end %>
app/controllers/users/sessions_controller.rb
class Users::SessionsController < Devise::SessionsController
def new
super
end
def create
self.resource = warden.authenticate!(auth_options)
set_flash_message(:notice, :signed_in) if is_navigational_format?
sign_in(resource_name, resource)
if !session[:return_to].blank?
redirect_to session[:return_to]
session[:return_to] = nil
else
respond_with resource, :location => after_sign_in_path_for(resource)
end
end
end
Any suggestions are most welcome.
Thank you in advance.
As you are taking the sessions contoller under the users name space,
devise_for :users, controllers: {
sessions: 'users/sessions',
registrations: 'users/registrations'
}
Your sessions_controller path should be,
app/controllers/users/sessions_controller.rb
class Users::SessionsController < Devise::SessionsController
def new
super
end
def create
self.resource = warden.authenticate!(auth_options)
set_flash_message(:notice, :signed_in) if is_navigational_format?
sign_in(resource_name, resource)
if !session[:return_to].blank?
redirect_to session[:return_to]
session[:return_to] = nil
else
respond_with resource, :location => after_sign_in_path_for(resource)
end
end
end
The form you have taken in the que should be in app/views/users/sessions/new.html.erb
<h2>Log in</h2>
<%= form_for(resource, as: resource_name, url: session_path(resource_name)) do |f| %>
<div class="field">
<%= f.label :email %><br />
<%= f.email_field :email, autofocus: true %>
</div>
<div class="field">
<%= f.label :password %><br />
<%= f.password_field :password, autocomplete: "off" %>
</div>
<% if devise_mapping.rememberable? -%>
<div class="field">
<%= f.check_box :remember_me %>
<%= f.label :remember_me %>
</div>
<% end -%>
<div class="actions">
<%= f.submit "Log in" %>
</div>
<% end %>
<%= render "users/shared/links" %>
If you change your controller in routes as
devise_for :users, controllers: {
registrations: 'registrations',
sessions: 'sessions',
passwords: 'passwords',
confirmations: 'confirmations',
}
and keep your controller as app/controllers/session_controller.rb will do the job.

Rails 4 routing error with nested comments form using nested resources

I was following this tutorial http://www.sitepoint.com/nested-comments-rails/ to implement nested comments for an image board. It worked fine until I made "comments" belong to "boards" and then had to nest my routes.
Here are my routes:
Rails.application.routes.draw do
root "boards#index"
devise_for :users do
get '/users/sign_out' => 'devise/sessions#destroy'
end
resources :boards do
resources :comments
get '/comments/new/(:parent_id)', to: 'comments#new', as: :new_comment
get '/comments/(:parent_id)', to: 'comments#destroy', as: :delete_comment
get '/comments/edit/(:parent_id)', to: 'comments#edit', as: :edit_comment
end
end
Here is my form:
<%= form_for [#board, #comment] do |f| %>
<% if #comment.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#comment.errors.count, "error") %> prohibited this comment from being saved:</h2>
<ul>
<% #comment.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<%= f.hidden_field :parent_id %>
<div class="form-group">
<% if #comment.parent_id == nil %>
<%= f.label :title %>
<%= f.text_field :title, class: 'form-control' %>
<% else %>
<% nil %>
<% end %>
</div>
<div class="form-group">
<%= f.radio_button(:user_id, current_user.id) %>
<%= f.label(:user_id, "I want to post as myself") %>
<%= f.radio_button(:user_id, nil) %>
<%= f.label(:user_id, "I want to post anonymously") %>
</div>
<div class="form-group">
<%= f.label :content %>
<%= f.text_area :content, class: 'form-control', required: true %>
</div>
<div class="form-group">
<%= f.label :image %>
<%= f.file_field :image %>
</div>
<%= f.submit class: 'btn btn-primary' %>
<% end %>
And here is my controller:
class CommentsController < ApplicationController
def index
#comments = Comment.hash_tree
end
def new
#comment = Comment.new(parent_id: params[:parent_id])
end
def edit
#comment = Comment.find(params[:parent_id])
end
def create
if params[:comment][:parent_id].to_i > 0
parent = Comment.find_by_id(params[:comment].delete(:parent_id))
#comment = parent.children.build(comment_params)
else
#comment = Comment.new(comment_params)
end
if #comment.save
redirect_to root_url
else
render 'new'
end
end
def update
#comment = Comment.find(params[:id])
if #comment.update(comment_params)
redirect_to #comment
else
render 'edit'
end
end
def make_parent
#comment.parent_id = nil
#comment.save
end
def destroy
#comment = Comment.find(params[:parent_id])
#comment.destroy
respond_to do |format|
format.html { redirect_to comments_url }
end
authorize! :destroy, #comment
end
private
def comment_params
params.require(:comment).permit(:title, :content, :user_id, :image)
end
end
I've tried setting a custom route in the form, this gets the form to at least appear, however when you hit the submit button it returns 'No route matches [POST] "/boards/1/comments/new"'. If I got to the controller and then change the corresponding "get" to a "post" then it causes the form to just reappear after pressing submit and nothing is added to the database. I've also experimented with shallow nesting my routes as per my instructors advice but this didn't work.
Your association between boards and comments must be:
board.rb
has_many :comments
comment.rb
belongs_to :user
routes.rb
resources :boards do
resources :comments, only: [:new, :edit, :destroy]
end
this will create a route
new_board_comment GET /boards/:board_id/comments/new(.:format) comments#new
edit_board_comment GET /boards/:board_id/comments/:id/edit(.:format) comments#edit
board_comment DELETE /boards/:board_id/comments/:id(.:format) comments#destroy

Sign up/Login Routing error

Sorry for the novice question but I am trying to get to grips with RoR. I have a very basic sign up and login process in place but am having some difficulty getting the routing correct. I am also unsure whether I am actually being logged out successfully when I push my logout button because it isn't then displaying the login button as it should.
My setup is as follows on Rails 3.1:
Sessions Controller
class SessionsController < ApplicationController
def new
end
def create
user = User.find_by_email(params[:email])
if user && user.authenticate(params[:password])
session[:user_id] = user.id
redirect_to root_url, :notice => "Logged in!"
else
flash.now.alert = "Invalid email or password!"
render "signup"
end
end
def destroy
session[:user_id] = nil
redirect_to root_url, :notice => "Logged Out!"
end
end
User Controller
class UserController < ApplicationController
def new
#user = User.new
end
def create
#user = User.new (params[:user])
if #user.save
redirect_to root_url, :notice => "Signed Up!"
else
render "user/new"
end
end
end
User Model
class User < ActiveRecord::Base
has_secure_password
validates_confirmation_of :password
validates_presence_of :password, :on => :create
validates_presence_of :email
validates_uniqueness_of :email, :on => :create
end
Sessions/new.html.erb
<h1>Log In</h1>
<%= form_tag login_path do %>
<div class="field">
<%= label_tag :email %>
<%= text_field_tag :email, params[:email] %>
</div>
<div class ="field">
<%= label_tag :password %>
<%= password_field_tag :password %>
</div>
<div class="actions"><%= submit_tag "Log in" %></div>
<%end%>
User/new.html.erb
<% if session[:user_id] %>
<!-- user is logged in -->
<%= link_to logout_path %>
<% else %>
<!-- user is not logged in -->
<%= link_to login_path %>
<% end %>
<h1>Sign Up</h1>
<%= form_for #user do |f| %>
<% if #user.errors.any? %>
<div class="error_messages">
<h2>Form is invalid</h2>
<ul>
<% for message in #user.errors.full_messages %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<div class = "field">
<%= f.label :email %>
<%= f.text_field :email %>
</div>
<div class = "field">
<%= f.label :password %>
<%= f.password_field :password %>
</div>
<div class = "field">
<%= f.label :password_confirmation %>
<%= f.password_field :password_confirmation %>
</div>
<div class="actions"><%= f.submit %></div>
<% end %>
Finally my Routes file
MadeByV2::Application.routes.draw do
controller :user do
get "signup" => "user#new"
end
resources :users
controller :sessions do
get "login" => "sessions#new"
post "login" => "sessions#create"
delete "logout" => "sessions#destroy"
end
root :to => "user#new"
end
Sorry for the extensive use of code in this post but I figure it's best to give a well rounded view of everything so people can see where I am going wrong.
Any help you can offer really would be much appreciated because I don't seem to be getting it myself
Thanks,
Tom
Your code looks fine, but your routes look a little strange.
I'd try something like this:
resources :users
resources :sessions
match 'login' => 'sessions#new', :as => :login
match 'logout' => 'sessions#destroy', :as => :logout
Then I think everything you've currently got should work.

Rails 3 RoutingError: No route matches {:controller=>"user_sessions"}

I'll just try to outline this as high level as I can. I am trying to access http://localhost:3000/login
The error is:
No route matches {:controller=>"user_sessions"}
And it's erroring on this line in the new.html.erb file below:
<%= form_for(#user_session) do |f| %>
The route in routes.rb is:
match 'login' => 'user_sessions#new', :as => :login
The user_sessions_controller.rb is:
class UserSessionsController < ApplicationController
def new
#user_session = UserSession.new
end
def create
#user_session = UserSession.new(params[:user_session])
if #user_session.save
flash[:notice] = "Successfully logged in."
redirect_to root_path
else
render :action => 'new'
end
end
def destroy
#user_session = UserSession.find
#user_session.destroy
flash[:notice] = "Successfully logged out."
redirect_to root_path
end
end
And the actual view for the login page is as follows (new.html.erb):
<h1>Login</h1>
<%= form_for(#user_session) do |f| %>
<% if #user_session.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#user_session.errors.count, "error") %> prohibited this user from being saved:</h2>
<ul>
<% #user_session.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<p>
<%= f.label :login %><br />
<%= f.text_field :login %>
</p>
<p>
<%= f.label :password %><br />
<%= f.password_field :password %>
</p>
<p><%= f.submit "Submit" %></p>
<% end %>
Thank you.
Using form_for(#user_session) alone will try to build out the path using a resource you have defined in your routes.rb. Which you currently don't have (I'm assuming, as you didn't mention it. Please correct if I'm wrong.).
A few ways to go..
Add a resource and limit to the ones you need
resources :user_sessions, :only => [:create, :destroy]
These will use the default routing namings, but you can custom that up as you need.
Match out the routes you need.
match 'login' => 'user_sessions#create', :as => :post_login, :via => :post
View
= form_for(#user_session), :url => post_login_path do |f|
...

Resources