Accessing Params in Rails 3.2 - ruby-on-rails

I am working through the RailsApps Stripe tutorial.
When a new subscriber is created through a devise registration controller they are then directed to their content page through a content controller. I want to use their name and email address created upon registration on their content page. But I can't seem to bring the params into the content controller.
I put#user = User.find(params[:id]) into the content_controller but I get the error "Couldn't find User without an ID".
On the error page it lists under Request Info > rack session: "warden.user.user.key"=>["User", [2],
So does that mean that ID of User #2 is being passed to the content_controller but that I can't access it?

I put#user = User.find(params[:id]) into the content_controller but I
get the error "Couldn't find User without an ID".
This error means that params[:id] = nil, i.e., you are not passing id in the params hash when redirecting the user to content page.
Possible Solutions:
With Devise you get a helper method called current_user which returns an instance of currently logged in user. So, you could directly use current_user to access the attributes of currently logged in user. For example:
To access name and email fields of currently logged in user, all you need to do is
current_user.name
current_user.email
In routes.rb, pass the id of the currently logged in user via the route of content page as below:
## Add :id dynamic segment to your content page route
get "content/:id", :to => "contents#action_name", :as => "content_page"
Since, I don't have the route details, you would need to modify the above route as per your requirement.
Next, when redirecting the user to content page after sign up just pass the currently logged in user as below in ApplicationController method named after_sign_up_path_for (You need to override this Devise method if you want to redirect the user to a different route than the default root path):
def after_sign_up_path_for(resource)
content_page_path(resource) ## Provide the path and pass resource to it
end

With Devise, you can access the currently logged in user via the current_user helper in your controller.
See documentation: https://github.com/plataformatec/devise#controller-filters-and-helpers

Related

Rails devise registration two ways after sign_up

I want devise to redirect to specific controller index action( or specific page) after user is sign_up.
In detail, i have an app with 2 ways to sign-up : for the client and for the Professor . Actually, the 2 type use the same registration page, it works very nice but when they sign_up they are automatically redirect to the same page ...
So, i want to change the way like this :
- when user click on I want to become Professor i want to register (full name, mail, password) and redirect after sign_up to the Professor dashboard
- and when user click on Client i want to register with the "same way" BUT in the end, i want to redirect to the client's dashboard.
So, i started to change devise.rb to change this
config.allow_unconfirmed_access_for = 2.days (automatically login after sign_up)
And in my RegistrationsController, i override the after_sign_up_path_for to have something like
def after_sign_up_path_for(resource)
if 'user is Prof'
redirect_path_professor
else
redirect_path_client
end
end
but how can i check (in condition) if user click on Prof. or Client ?. Its the same resource (registration) ^^
Thanks
Why not using only one link, then let the user selects his role in the registration view?
If you really want two links for the same view, you should pass the role in a param (something link link_to 'Becoming a Professor', new_registration_path(role: 'professor'), then add an hidden_field in your registration form with the value of the param.
= f.input :role, as: :hidden, input_html: { value: params[:role] }
But don't forget to validate the content of the params to avoid the bad values sent by teasing users
Also, after_sign_in_path_for(resource) should be in application_controller. You'll need a column in users to specify the role, and your method will looks like something like this:
def after_sign_in_path_for(resource)
stored_location_for(resource) || (resource.role.professor? ? professor_dashboard_url : user_dashboard_url(resource))
end

How to access current user with Devise

I am using devise as well as ldap in my application to authenticate users. I have got the users model set up as well as devise. I can properly sign in and sign out users but I cannot access any information for the devise built in helper; current_user.
I want the main page of the application to show the current users name at the top of the page. I have created the column in the users table called display_name.
This is the code that I want to work:
<% if user_signed_in? %>
<div> <%= current_user.display_name %> </div>
<% end %>
When I used byebug and try to access the current user it returns nil.
Does anyone have any suggestions on how I can access the current users information?
Update
I tried using: <% if signed_in %>
but i still get the same error: undefined method `display_name' for nil:NilClass
devise documentation says:
If your devise model is something other than User, replace "_user"
with "_yourmodel".
Is your model User? If not, you need to use the appropriate helper method.
Which LDAP gem are you using? devise_ldap_authenticatable ?
You will need to define an instance variable #current_user in your ApplicationController, and set it to the correct user record based on the LDAP account which authenticated.
Then, during sign-in you need to set the value of #current_user, and during sign-out you need to set it to nil.
So for sign-in and sign-out you would have to implement this in Session#create and Session#destroy

Routing to profile page by username

I am working on a social media site and I am having a problem with routing.
Every user has a profile page like facebook and this is the root I use:
get 'profile(/:id)' => 'profiles#show'
So, when the URL is like this: www.sitename.com/profile/1 it opens up the page belongs to user with id 1. But, I also want users to be able to use their usernames in url without /profile/. So it is gonna be like facebook.
For example: www.sitename.com/handsomeboy69
How can I do this in routing? Because, rails may think that username passed in URL is a page name.
Thank you
I fixed it. This is the route I used:
get ':username' => 'profiles#show'
In the controller I used this statement:
if params.has_key?(:username)
#profile = User.find_by_username(params[:username])
elsif params.has_key?(:id)
#profile = User.find(params[:id])
else
end
else statement at the end is empty, I am gonna use that area to print out error message saying that profile cannot be found.
and most important part is that this routing should be at the end of the file.

I'm having trouble viewing other users in my app

In the users controller for my app I have a method for viewing the posts generated by users, but when you go to the index page and click on another user, the page of the currently logged in user shows up but the url is for the user I just clicked onto.
This is the method in my users controller
def feed
#title = "Feed"
#user = User.find(session[:user_id]) # This is the problem
feed = Feed.new(#user)
render 'show_feed'
end
I'm also having trouble understanding the difference between session[:user_id] and params[:id]. If I change session[:user_id] to params[:id] while on the page, of the user I just clicked onto, their posts are then shown, but when I go back to the logged in user's page I get the error "Couldn't find User with 'id'=user_id" in "app/controllers/users_controller.rb:59:in `feed'" So my question is, what do I need to pass into #user = User.find() to get the correctly generated page/s?
Generally if you're clickiing on a link to see some OTHER user, the link has an "id" embedded in it which is passed in the params, so you would do...
#user = User.find(params[:id])
Your link to go back to the logged in user is incorrect, but you haven't shown that link. It should most probably be something like
<%= link_to user_path(session[:user_id]) %>
From the description of your problem you may be doing...
<%= link_to user_path('user_id') %>
... which doesn't make sense... it means literally go to the user record with the id of "user_id"
session is data (usually stored in a cookie) that is persistent from one request to another and that expires at the end of the browser session. A common use is to store the id of the logged in user.
By passing that to User.find you're entirely ignoring the user id that is in the URL. You should be using params[:id] (unless your routes are naming that segment of your url differently)
Your problem when you "go back" is not clear to me (I can't even tell if we're talking about the same controller action) but at a guess either that page doesn't have an id in the URL, or the routing is calling it something else, or (and this is a little messy) you intend to fall back to the current user when there is no id in the URL in which case you need to be using either params[:id] or session[:user_id] depending on what's there.

'Cannot redirect to nil' error after adding a field to devise registration view

After adding this line to the devise/registrations/new.html.haml file (view):
%div
= f.label :account_type
%br/
= f.select(:account_type, [["Usertype1","usertype1"],["Usertype2","usertype2"]], {:selected => nil, :prompt => 'Pick One'})
I get the following error after clicking on the confirmation link in the confirmation e-mail:
ActionController::ActionControllerError in Devise::ConfirmationsController#show
Cannot redirect to nil!
It only happens if I select Usertype2 upon registration. I also made the account_type attr_accessible. The account_type seems to be getting assigned (I checked in the rails console) and the development logs don't have any further information.
I think this is the line in the devise confirmations controller where the error is occurring:
respond_with_navigational(resource){ redirect_to after_confirmation_path_for(resource_name, resource) }
Also, the account is being confirmed, but when trying to log in, I get the following:
undefined method `user_url' for #<Devise::SessionsController:0x9d1659c>
which is in the create action of the devise sessions controller.
Any help would be appreciated. Thanks!
John
The two errors you mentioned are one and the same, essentially when you are signing-in successfully Devise is unable to detect where to redirect you. This problem often occurs when you have multiple models or try to setup a custom redirect (post sign in) in the routes file.
Try to define the path in the ApplicationController.
Devise docs say that the after_sign_in_path_for method takes the actual model object (ie: the model being signed-in)
def after_sign_in_path_for(resource)
signed_in_path_for_user
end
Note: You can do the same for several Devise paths / variables (override them). Also for more information on doing this for multiple Devise models in the same app, you can look at this question and it's answer.

Resources