This is method in the users_controller.rb
def create
#user = User.new(params[:user])
if #user.save
sign_in #user
flash[:success] = "Welcome to the Sample App!"
redirect_to #user
else
render 'new'
end
end
Here the code
redirect_to #user
automatically redirect to the show action, can anybody explain it ?
You succesfully created a User. As a result, you are redirected to the user you just created through it's newly created id. Redirect_to means you are redirecting to an other action, in this case the show action. In other words, you are no longer using #user from your create action, but #user from your show action (User.find(params[:id]). If you would change the redirect_to #user to redirect_to #users you would be redirected to the index action of user upon succesfull creation.
If you would like a bit more detail: http://api.rubyonrails.org/classes/ActionController/Base.html
For example:
"Unlike index, the create action will not render a template. After performing its main purpose (creating a new post), it initiates a redirect instead. This redirect works by returning an external “302 Moved” HTTP response that takes the user to the show or index action, depending on the redirect."
Related
I've been pulling my hair out trying to get anything working with "def create" and "def update" in the users_controller.rb for Devise.
For instance, I've tried this:
def create
#user = User.new(params[:user])
respond_to do |format|
if #user.save
flash[:notice] = "Test Save"
else
flash[:notice] = "Test Error"
end
end
end
I've used this code along with the appropriate code to show flash notices in the views section. However nothing is shown when I either submit a blank form, an incomplete form, or a complete form. The user registration will still go through on a complete form, but it does not follow anything I put in "def create". I've tried other ways of testing this aside from flash notices, such as sending to a different page, etc. I get no response. The same thing for "def update", it doesn't seem to even use that code.
I'm completely dumbfounded on this one, any ideas?
If i understand your question correctly, you should be overwriting the devise controller.
# app/controllers/registrations_controller.rb
class RegistrationsController < Devise::RegistrationsController
def new
super
end
def create
# add custom create logic here
end
def update
super
end
end
You can see what the default devise controllers are doing here:
https://github.com/plataformatec/devise/tree/master/app/controllers/devise
If you just want to edit the flash message, looking at the link above shows that devise uses a method called set_flash_message
# Sets the flash message with :key, using I18n. By default you are able
# to setup your messages using specific resource scope, and if no one is
# found we look to default scope.
# Example (i18n locale file):
#
# en:
# devise:
# registrations:
# signed_up: 'Welcome! You have signed up successfully.'
So you can just edit your devise.en.yml file with the correct text and voila!
Note: If you do overwrite the controller don't forget to also add
# app/config/routes.rb
devise_for :users, :controllers => {:registrations => "registrations"}
How about this instead?
if #user.save
redirect_to #user, notice: 'User was successfully created.'
else
render action: 'new'
end
You are setting the flash, but no redirection and no rendering. I'm wondering if you are getting a blank page, or a 200 with no body.
This will redirect to the show action, setting a flash notice if successful and render the new form with the #user.errors showing why it failed.
If you are using devise, you could use the Registrations Controller to create a new account, you shouldn't need to create a new one. If you create a new one, there might be a conflict in the routes with registrations#create and users#create both pointing to POST /users
I'm doing a sort of notepad in rails. the main page has this form for notes with the only field "content". Everyone can create a note but I'm trying to add authentication using devise so users can sign up and save their notes.
So I have my site controller with index as uniq method
site controller
def index
#note = Note.new
end
and then a notes controller with the create action
notes controller
def create
#note = if user_signed_in?
current_user.notes.build(params[:note])
else
Note.new(params[:note])
end
respond_to do |format|
if #note.save
format.js
else
format.js
end
end
end
I though that would work but devise helpers only seems to work when I add
before_filter :authenticate_user!
on the controller I need.
is it possible to check if there's a user without the before_filter? or should I make 2 create methods?
As a workaround you can try to add this before filter:
before_filter :authenticate_user!, :only => []
It might add the helpers (if it's really needed) but won't apply to any action.
I want to show a devise user provide inside another view.
Homeprivate/profile.html.erb:
<%= render "devise/registrations/edit" %>
I just converted the default edit view into a partial. To support the user to be available as a "resource", I have the following helper.
module HomeprivateHelper
def resource_name
:user
end
def resource
#resource ||= User.new
end
def devise_mapping
#devise_mapping ||= Devise.mappings[:user]
end
end
But if I sign in, and go to /homeprivate/profile -- I see all fields are empty. Somehow the current user is not mapped to the form. How do I map the current user to the profile view if it is displayed in a custom view? Seems like User.new is used, not the current user.
I'm fairly new to rails, but I got the same issue and figured out how to fill those empty fields. In your helper, instead of user.new use current_user. It should look like this:
def resource
#resource ||= current_user
end
That should work.
I am trying to replace user profile views of the sort
/users/1
with
/username
I'm aware this means I'll need to check for collisions of various kinds. I've consulted the following similar SO questions:
Ruby on rails routing matching username
customize rails url with username
Routing in Rails making the Username an URL:
routing error with :username in url
Here are the various failed routes.rb route definitions I've tried, and associated errors:
match "/:username" => "users#show", via: "get"
Here's the error:
ActiveRecord::RecordNotFound in UsersController#show
Couldn't find User without an ID
app/controllers/users_controller.rb:7:in `show'
Here is my corresponding users_controller:
6 def show
7 #user = User.find(params[:id])
8 end
match "/:username" => 'users#show', :as => :profile
Same error as above.
match "/:username", :controller => "users/:id", :action => 'show'
Routing Error
uninitialized constant Users
Try running rake routes for more information on available routes.
match '/:username', :controller => 'users', :action => 'show'
Same error as 1.
match '/:username', to: 'users/:id', via: 'show'
Server does not start.
match "/:username" => redirect("/users/:id")
Error:
ActiveRecord::RecordNotFound in UsersController#show
Couldn't find User with id=:id
Any idea why my routing is not working the same way that everyone else who asks this question's is?
Update
Just to take this issue out of the comments and put it in the question more cleanly. After making the change by #Ryan Bigg below, I had a routing problem in my redirect to profile when a new one is created. Here's my create code:
def create
#user = User.new(params[:user])
if #user.save
session[:user_id] = #user.id
flash[:success] = "Thank you for signing up."
redirect_to ('/'+#user.username)
#redirect_to #user, notice: "Thank you for signing up!"
else
render "new"
end
end
And here is my user.rb
def to_param
self.username
#username
end
However, the commented out redirect, which I think should work with the to_param update, doesn't work, while the ugly hackish one above it does. Why is the to_param overwrite, which worked for other people, not working on my app? My #update and #edit methods are also not working, as their redirects go to "users/1/edit" instead of "username/edit" if overwriting to_param doesn't take care of this.
The first one is correct, but isn't working because you're still attempting to do something like this inside your controller:
User.find(params[:username])
When you should instead be doing this:
User.find_by_username!(params[:username])
The first one will attempt to find by the primary key of your table, where the second one will, correctly, query on the username field instead.
In addition to the update for to_params, the bottom of the routes file needs the following line:
resources :users, :path => '/'
I'm using Devise for the first time with rails, and I'm having trouble with one thing:
I used the provided authenticate_user! method in my user's controller to restrict access to pages like so:
before_filter :authenticate_user!, :only => [:edit, :show, :update, :create, :destroy]
But this allows any signed in user to access any other users :edit action, which I want to restrict to only that user. How would I do that?
In your edit method, you need to do a check to see if the user owns the record:
def edit
#record = Record.find(params[:id])
if #record.user == current_user
#record.update_attributes(params[:record])
else
redirect_to root_path
end
end
You should look into Authorization such as CanCan. Or alternatively create a new method like so:
# Create an admin boolean column for your user table.
def authenticate_admin!
authenticate_user! and current_user.admin?
end