Rails add new view to devise - ruby-on-rails

I have generated views with this command after I installed devise
rails generate devise:views
and I override registration controller by
class RegistrationsController < Devise::RegistrationsController
def sign_up2
end
end
And updated routes.rb with
devise_for :users, :controllers => { :registrations => "registrations" }
I expected to see a new route/view of
/users/sign_up2
but I don't see it
And here routes for devise
new_user_session GET /users/sign_in(.:format) devise/sessions#new
user_session POST /users/sign_in(.:format) devise/sessions#create
destroy_user_session DELETE /users/sign_out(.:format) devise/sessions#destroy
user_password POST /users/password(.:format) devise/passwords#create
new_user_password GET /users/password/new(.:format) devise/passwords#new
edit_user_password GET /users/password/edit(.:format) devise/passwords#edit
PATCH /users/password(.:format) devise/passwords#update
PUT /users/password(.:format) devise/passwords#update
cancel_user_registration GET /users/cancel(.:format) registrations#cancel
user_registration POST /users(.:format) registrations#create
new_user_registration GET /users/sign_up(.:format) registrations#new
edit_user_registration GET /users/edit(.:format) registrations#edit
PATCH /users(.:format) registrations#update
PUT /users(.:format) registrations#update
DELETE /users(.:format) registrations#destroy
But I would like a new view and route
Update:
issue when I load view
First argument in form cannot contain nil or be empty
in this line
<%= form_for(resource, :as => resource_name,:html => { :class => "form-horizontal col-sm-12",:role=>"form"}, :url => user_registration_path(resource_name)) do |f| %>

Invoke a devise_scope block and declare your custom route within:
devise_for :users, :controllers => { :registrations => "registrations" }
devise_scope :user do
get "users/sign_up2"=> "users/registrations#sign_up2", :as => "sign_up2_registration"
end
The section on Configuring routes in the documentation provides the following explanation of devise_scope:
If you have the need for more deep customization, for instance to also allow "/sign_in" besides "/users/sign_in", all you need to do is to create your routes normally and wrap them in a devise_scope block in the router
Previously, Devise allowed custom routes to be passed as a block to devise_for, but this behavior has been deprecated.
UPDATE:
To address the First argument in form cannot contain nil or be empty error, you need to ensure that your custom sign_up2 action is properly setting the resource variable. Assuming you want to mimic the registrations/new action, you can do something akin to the following:
def sign_up2
build_resource({})
respond_with self.resource
end
This ensures that the resource variable in your view is not nil and will not throw the exception you're currently witnessing.
Alternatively, depending on the behavior you're trying to evince, you can set your own instance variable in the custom controller action, then pass it as the resource to your form_for tag:
# app/controllers/users/registrations_controller.rb
def sign_up_2
#new_registrant = Registrant.new
end
# app/views/users/sign_up2.html.erb
<%= form_for(#new_registrant, :as => resource_name,:html => { :class => "form-horizontal col-sm-12",:role=>"form"}, :url => user_registration_path(resource_name)) do |f| %>
However, if you follow this approach, you should consider why you need to roll this into Devise. Devise, by default, assigns the resource variable via the build_resource function. If you're going to override/bypass this function, you should consider abstracting this entire functionality out of Devise since you're totally circumventing its default behavior.

Related

undefined local variable or method with form_tag

I'm trying to create a simple search form in my Rails application. I get an error with the url path of the form:
<%= form_tag(med_search, :method => "get", id: "search-form") do %>
<%= text_field_tag :search, params[:search], placeholder: "Search", class: "form-control" %>
<%= button_to "Search", class: "btn btn-default" %>
<% end %>
The first line above causes error undefined local variable or methodmed_search' for #<#:0x007fab2b5afa90>`
The problem is most likely with my routes setup. I created a new controller action called search so I edited my routes.db to look like this:
resources :meds do
collection do
get 'search' => 'meds#search'
end
end
devise_for :users
#get 'meds/index'
root to: "meds#index"
resources :meds, :path => ''
end
When I do rake routes, I am seeing the path med search so I know the url is valid:
Prefix Verb URI Pattern Controller#Action
med_search GET /meds/:med_id/search(.:format) meds#search
meds GET /meds(.:format) meds#index
POST /meds(.:format) meds#create
new_med GET /meds/new(.:format) meds#new
edit_med GET /meds/:id/edit(.:format) meds#edit
med GET /meds/:id(.:format) meds#show
PATCH /meds/:id(.:format) meds#update
PUT /meds/:id(.:format) meds#update
DELETE /meds/:id(.:format) meds#destroy
new_user_session GET /users/sign_in(.:format) devise/sessions#new
user_session POST /users/sign_in(.:format) devise/sessions#create
destroy_user_session DELETE /users/sign_out(.:format) devise/sessions#destroy
user_password POST /users/password(.:format) devise/passwords#create
new_user_password GET /users/password/new(.:format) devise/passwords#new
edit_user_password GET /users/password/edit(.:format) devise/passwords#edit
PATCH /users/password(.:format) devise/passwords#update
PUT /users/password(.:format) devise/passwords#update
cancel_user_registration GET /users/cancel(.:format) devise/registrations#cancel
user_registration POST /users(.:format) devise/registrations#create
new_user_registration GET /users/sign_up(.:format) devise/registrations#new
edit_user_registration GET /users/edit(.:format) devise/registrations#edit
PATCH /users(.:format) devise/registrations#update
PUT /users(.:format) devise/registrations#update
DELETE /users(.:format) devise/registrations#destroy
root GET / meds#index
GET / meds#index
POST / meds#create
GET /new(.:format) meds#new
GET /:id/edit(.:format) meds#edit
GET /:id(.:format) meds#show
PATCH /:id(.:format) meds#update
PUT /:id(.:format) meds#update
DELETE /:id(.:format) meds#destroy
What should I change in the routes to fix this?
Thanks!
EDIT: changed url to med_search_path, get new error: No route matches {:action=>"search", :controller=>"meds"} missing required keys: [:med_id]. Looks like it's related to the route /meds/:med_id/search(.:format)
1) you need to change your form_tag like this
<%= form_tag(search_meds_path, :method => "get", id: "search-form") do %>
2) You need to change your route from member to collection like this
resources :meds do
collection do
get 'search' => 'meds#search'
end
end
3) Not sure why you need to add resources :meds, :path => '' at the bottom again. Incase you dont need it, it is better to remove.
It looks like you're trying to code up a search but because you put it in the resources block Rails is assuming you're talking about a specific med.
Remove the route from the resources block and change it to get 'meds/search' => 'meds#search'. That will allow you to use it as just a regular endpoint without Rails complaining that you need an ID.

How to use Devise both in the site and in the Admin Pages

I'm new to RoR and Devise and i'm stuck in User Authentications with Devise. I'm developing a web site, which has admin pages in it. My structure looks like this:
app
|-controllers
|-admin
|- user_list_controller.rb //Every user crud operations are in it.
|-views
|-admin
|-user_list
|-new.html.erb
|-edit.html.erb
|-devise //Also have devise views
UserListController:
class Admin::UserListController < ApplicationController
layout 'admin/admin'
def index
#user_list = User.all
end
def new
#user = User.new
end
def edit
end
def delete
end
def create_user
end
end
What I want to do is that, I want to use Devise methods under this controller but this is where I stuck in. I created a UserController which base is Devise::RegistrationsController. But this time I got this error,
Could not find devise mapping for path "/admin/create_user". This may
happen for two reasons: 1) You forgot to wrap your route inside the
scope block. For example: devise_scope :user do get "/some/route" =>
"some_devise_controller" end 2) You are testing a Devise controller
bypassing the router. If so, you can explicitly tell Devise which
mapping to use: #request.env["devise.mapping"] =
Devise.mappings[:user]
It looks like a route.rb error and my route file is:
Rails.application.routes.draw do
devise_for :users
devise_scope :user do
# post "admin/add_user" =>"admin/user_list#create_user", as: :adduser
end
namespace :admin do
root to: 'admin#index'
get 'user_list', :to => 'user_list#index'
post 'create_user', :to => "user#create"
get 'new_user', :to => 'user_list#new'
get 'user_proposals', :to => 'user_proposal_forms#index'
get 'user_appointments', :to => 'user_appointments#index'
get 'brands', :to => 'brands#index'
get 'brand_makes', :to => 'brand_makes#index'
get 'make_types', :to => 'make_types#index'
end
end
And the result of rake routes is this:
Prefix Verb URI Pattern Controller#Action new_user_session GET /users/sign_in(.:format) devise/sessions#new
user_session POST /users/sign_in(.:format) devise/sessions#create
destroy_user_session DELETE /users/sign_out(.:format) devise/sessions#destroy
user_password POST /users/password(.:format) devise/passwords#create
new_user_password GET /users/password/new(.:format) devise/passwords#new
edit_user_password GET /users/password/edit(.:format) devise/passwords#edit
PATCH /users/password(.:format) devise/passwords#update
PUT /users/password(.:format) devise/passwords#update
cancel_user_registration GET /users/cancel(.:format) devise/registrations#cancel
user_registration POST /users(.:format) devise/registrations#create
new_user_registration GET /users/sign_up(.:format)devise/registrations#new edit_user_registration GET /users/edit(.:format) devise/registrations#edit
PATCH /users(.:format) devise/registrations#update
PUT /users(.:format) devise/registrations#update
DELETE /users(.:format) devise/registrations#destroy
admin_root GET /admin(.:format) admin/admin#index
admin_user_list GET /admin/user_list(.:format) admin/user_list#index
admin_create_user POST /admin/create_user(.:format) admin/user#create
admin_new_user GET /admin/new_user(.:format) admin/user_list#new
admin_user_proposalsGET /admin/user_proposals(.:format) admin/user_proposal_forms#index
admin_user_appointments GET /admin/user_appointments(.:format) admin/user_appointments#index
admin_brands GET /admin/brands(.:format) admin/brands#index
admin_brand_makes GET /admin/brand_makes(.:format) admin/brand_makes#index
admin_make_types GET /admin/make_types(.:format) admin/make_types#index
It looks messy, sorry for that. Finally my form_for looks like this:
<%= simple_form_for #user, url: admin_create_user_path, class: "form-horizontal" do |f| %>
<%= render(:partial => "form", :locals => {:f => f}) %>
<% end %>
So where did I make a mistake? I've read all the documents in Devise, tried so many things but couldn't solve the problem.
In routes file use
devise_for :users, :controllers => { registrations: 'registrations' }

Devise routing issues with admin role

I'm trying to add Devise to an existing Rails 3.2.16 app.
I have the basics working, but I'd like to create an admin role that is able to edit any user profile without entering a password.
I used the code from Option 2 - Adding an admin attribute in the Devise Wiki "Add An Admin Role" section to set up the admin role.
My routes.rb has this:
devise_for :users, :controllers => { :registrations => :registrations }
scope "/admin" do
resources :users
end
This gives me the following routes
new_user_session GET /users/sign_in(.:format) devise/sessions#new
user_session POST /users/sign_in(.:format) devise/sessions#create
destroy_user_session DELETE /users/sign_out(.:format) devise/sessions#destroy
user_password POST /users/password(.:format) devise/passwords#create
new_user_password GET /users/password/new(.:format) devise/passwords#new
edit_user_password GET /users/password/edit(.:format)devise/passwords#edit
PUT /users/password(.:format) devise/passwords#update
cancel_user_registration GET /users/cancel(.:format) registrations#cancel
user_registration POST /users(.:format) registrations#create
new_user_registration GET /users/sign_up(.:format) registrations#new
edit_user_registration GET /users/edit(.:format) registrations#edit
PUT /users(.:format) registrations#update
DELETE /users(.:format) registrations#destroy
admin_edit_user GET /admin/users/:id/edit(.:format) users/registrations#edit
users GET /admin/users(.:format) users#index
POST /admin/users(.:format) users#create
new_user GET /admin/users/new(.:format) users#new
edit_user GET /admin/users/:id/edit(.:format) users#edit
user GET /admin/users/:id(.:format) users#show
PUT /admin/users/:id(.:format) users#update
DELETE /admin/users/:id(.:format) users#destroy
The user views (devise/registrations/edit, etc) are hooked up correctly and work just fine, but the admin views are all pulled from the users folder (users/edit, etc), which means they bypass Devise.
For instance, my admin user edit form should probably have some variation on this in the form_for:
<%= form_for(resource, :as => resource_name, :url => registration_path(resource_name)) do |f| %>
but that code doesn't pull in any of the user data (all form fields are empty). The only way I can get it to show up is with the old code:
<%= form_for #user do |f| %>
Which then uses the update method from my users_controller, NOT from the Devise registrations_controller.
I've tried lots of variations on the routes because that seems to be key, but non of my attempts have worked. Help?
In order for your form_for helper to properly route your request through Devise, you need to declare your admin/users resource routes as Devise routes:
# config/routes.rb
devise_for :users, :controllers => { :registrations => :registrations }
scope "/admin" do
devise_for :users, :controllers => { :registrations => :registrations }
end
You'll continue to retain Devise functionality while being able to utilize the admin namespace for authorization purposes.

route in rake routes but page says No route matches [GET] with devise

I have added custom routes for the devise actions. this does not work when I try to go to /profile/edit or /login or /logout Here is the rake routes:
saasbook#saasbook:~/Documents/ronde$ rake routes
static_about GET /static/about(.:format) static#about
static_tour GET /static/tour(.:format) static#tour
static_home GET /static/home(.:format) static#home
static_terms_of_use GET /static/terms_of_use(.:format) static#terms_of_use
static_contact GET /static/contact(.:format) static#contact
users_profile GET /users/profile(.:format) registrations#edit
login GET /login(.:format) devise/sessions#new
logout GET /logout(.:format) devise/sessions#destroy
register GET /register(.:format) devise/registrations#new
profile_edit GET /profile/edit(.:format) devise/registrations#edit
new_user_session GET /users/sign_in(.:format) devise/sessions#new
user_session POST /users/sign_in(.:format) devise/sessions#create
destroy_user_session GET /users/sign_out(.:format) devise/sessions#destroy
user_omniauth_authorize GET|POST /users/auth/:provider(.:format) omniauth_callbacks#passthru {:provider=>/google|facebook/}
user_omniauth_callback GET|POST /users/auth/:action/callback(.:format) omniauth_callbacks#(?-mix:google|facebook)
user_password POST /users/password(.:format) devise/passwords#create
new_user_password GET /users/password/new(.:format) devise/passwords#new
edit_user_password GET /users/password/edit(.:format) devise/passwords#edit
PUT /users/password(.:format) devise/passwords#update
cancel_user_registration GET /users/cancel(.:format) devise/registrations#cancel
user_registration POST /users(.:format) devise/registrations#create
new_user_registration GET /users/sign_up(.:format) devise/registrations#new
edit_user_registration GET /users/edit(.:format) devise/registrations#edit
PUT /users(.:format) devise/registrations#update
DELETE /users(.:format) devise/registrations#destroy
root / static#home
Here is my routes.rb file where I added the the new routes with the same controller actions for devise:
Ronde::Application.routes.draw do
get "static/about"
get "static/tour"
get "static/home"
get "static/terms_of_use"
get "static/contact"
get "/user/profile", :to => 'registrations#edit'
get "/login", :to => "devise/sessions#new" # Add a custom sign in route for user sign in
get "/logout", :to => "devise/sessions#destroy" # Add a custom sing out route for user sign out
get "/register", :to => "devise/registrations#new" # Add a Custom Route for Registrations
get "profile/edit", :to => "devise/registrations#edit"
devise_for :users, :controllers => { :omniauth_callbacks => "omniauth_callbacks" }
root to: 'static#home'
end
# :path_names => {:edit => "profile/edit", :sign_in => "login", :sign_out => "logout", :sign_up => "register" }
Then page says that and should route to the devise controller:
Routing Error
No route matches [GET] "/profile/edit"
Try running rake routes for more information on available routes.
I don't know if this right but I think you can't do that way, because Devise doesn't have any controller. Please check this question and this.
What I done usually was making another controller for Devise, or normal controller like users_controller with it own views. And register it on routes.rb like:
devise_for :users
scope "/admin" do
resources :users
end
Then when I need to open it, I called localhost:3000/admin/users
But please correct me if there anything wrong, or my way to do it was wrong. Hope can help.

Devise with Rails 4: user show route doesn't exist

I am using the devise gem to handle all the sign up and sign in stuff. But I also want to add user profiles to my application, so I generated a user controller with only a show action. Then I added get 'users/:id' => 'users#show' to routes.rb. In fact, typing /users/1 works, but I can't find a way to name the route. What I want is to get something like show_user_path or user_path so I can link to a given user's content and show that user's profile.
Here is my routes.rb
Pinteresting::Application.routes.draw do
resources :pins
get 'users/:id' => 'users#show'
devise_for :users
root "pins#index"
get "about" => "pages#about"
And here are the routes I get with it (I highlighted the one I expect to be something like show_user_path):
pins_path GET /pins(.:format) pins#index
POST /pins(.:format) pins#create
new_pin_path GET /pins/new(.:format) pins#new
edit_pin_path GET /pins/:id/edit(.:format) pins#edit
pin_path GET /pins/:id(.:format) pins#show
PATCH /pins/:id(.:format) pins#update
PUT /pins/:id(.:format) pins#update
DELETE /pins/:id(.:format) pins#destroy
#this is the one I want a path! GET /users/:id(.:format) users#show
new_user_session_path GET /users/sign_in(.:format) devise/sessions#new
user_session_path POST /users/sign_in(.:format) devise/sessions#create
destroy_user_session_path DELETE /users/sign_out(.:format) devise/sessions#destroy
user_password_path POST /users/password(.:format) devise/passwords#create
new_user_password_path GET /users/password/new(.:format) devise/passwords#new
edit_user_password_path GET /users/password/edit(.:format) devise/passwords#edit
PATCH /users/password(.:format) devise/passwords#update
PUT /users/password(.:format) devise/passwords#update
cancel_user_registration_path GET /users/cancel(.:format) devise/registrations#cancel
user_registration_path POST /users(.:format) devise/registrations#create
new_user_registration_path GET /users/sign_up(.:format) devise/registrations#new
edit_user_registration_path GET /users/edit(.:format) devise/registrations#edit
PATCH /users(.:format) devise/registrations#update
PUT /users(.:format) devise/registrations#update
DELETE /users(.:format) devise/registrations#destroy
root_path GET / pins#index
about_path GET /about(.:format) pages#about
For devise, User is not the resource, it's just a scope. What devise cares about is authentication.
Although the paths are nested under /user, you will notice that the resources that are defined are actually things like sessions, registrations, passwords...
Just add resources :users in your routes and create a UsersController (and the views).
If you don't want to create all the resources for users and just be able to user user_path(user) with your get 'users/:id, you can name that route using the as option, like this:
get 'users/:id' => 'users#show', as: user
The answer above is great but I think it's worth noting here that if you don't want to create a different controller, but want to add an action to, say, your registrations controller that you inherit from the Devise::RegistrationsController, then you need to use the devise scope block:
devise_scope :user do
get 'users/:id' => 'registrations#show', as: user
end
the answer supposed to be like this:
get 'user/:id' => 'users#show', as: :user

Resources