Rails 3 - Routing to a user profile - ruby-on-rails-3

Greetings all, newbie to Rails here. I'm currently having issues routing /profile to the current user's profile.
My route is as follows:
match "profile" => "users#show"
However, this is hitting me with the "Couldn't find User without an ID" error. I know it has to do with my show method in the Users Controller. That code is simply:
def show
#user = User.find(params[:id])
end
Now, I could add another method in my Users controller with "#user = current_user" and it works fine. However, it seems a bit redundant and would also require a copy of the show view page. From what I've gathered with Rails, it's all about keeping things neat and tidy.
I would appreciate it if someone could point me in the right direction. Thank you.

RailsGuides states:
Because you might want to use the same controller for a singular route (/account) and a plural route (/accounts/45), singular resources map to plural controllers.
So I think you want to change your code to be the following
def show
#user = !params[:id].nil? ? User.find(params[:id]) : current_user
end

Related

Github like dynamic routes

What would be the best way to implement routes like github uses?
Ex:
github.com/about
github.com/37signals
github.com/javan
I'm guessing /about is a real controller, but the second and third probably load a user controller. What is the best way to do this?
Write a route like match '/:id/' => 'user#show' for a user like javan and have the show action in the user controller look up the user by username.
So in the user controller:
#user = User.find_by_username(params[:id])
You can learn more about routes here.

How to customize active admin comments feature in rails 3

I need to send an email whenever the admin add a comment to a user.
I am using active admin 0.4.3
How can I get this event and send email. When I post a comment, In my console I can see the following actions performed
Started POST "/admin/comments"
Redirected to http://localhost:3000/admin/comments/182
Started GET "/admin/comments/182"
Started GET "/admin/accounts/227"
I dont know how to access these functions. Please help.
I got it working by adding this code into your config/initializers/...
module ActiveAdmin
class Comment < ActiveRecord::Base
after_create :send_email
def send_email
AdminMailer.comment_created(self.id).deliver
end
end
end
Please mind that you have to write the AdminMailer and that we only pass the id because our mailer uses redis to send the mail asynchronous. If you don't have this you can pass the object.
I tried to overwrite the create action of the Admin::CommentsController in the same way but it didn't work. It would be much nicer to have this in the controller because sending an email is more a business of the controller than of the model. Any ideas how to do this?
...ok...commented on an active admin issue which adresses the same question and got some good answers...
As this is controller logic the best is to put it in the controller.
You can take a look at https://github.com/activeadmin/activeadmin/issues/2493#issuecomment-24892236
Basically, for modifying the Comment controller you have to do it after loading:
ActiveAdmin.after_load do
ActiveAdmin.register ActiveAdmin::Comment, as: 'Comment' do
controller do
after_action :send_email, only: [:create]
def send_email
AdminMailer.comment_created(self.id).deliver
end
end
end
end

Devise: Load a partial instead of showing a notice for non confirmed members

Is there a way to load a view for no confirmed users that login?
Default behaviour is to show a notice: " You have to confirm your account before continuing."
I tried
overrule the sessions#create method of devise checking for current_user.confirmed_at.blank?
in the after_singin_path check for current_user.confirmed_at.blank? and render the view instead
My goal is to render a custom view instead of the notice but cannot hook into the right location. Who knows how to accomplish this? thx!
You can simply copy the code from the devise github and place in your controllers/devise. then change any action or method you want to.
You may also just extend the devise session controller and override any action you want to.
class Abc < Devise::SessionsController
# this just reopens the class.
# Remember classes are never "closed" in ruby!
end
I like the ruby way of solving this, I guess that in your UsersController after a POST request the user will be returned and signed in using the sign_in(Object) helper Devise provides.
Also I suggest using a confirmed boolean instead of timestamp.
Why not check for the value using an if else statement the ruby way:
user.confirmed ? sign_in(user) : render :partial => 'path/partial'
Hope this might help you out

Passing controller method attributes in before_filter methods in Rails 3

I'm trying to only allow access to galleries by users who have permission to view them. Galleries have many shared_users through permissions, and vice versa. Galleries also have only one owner. Owners and shared users are both of the User class. This all works fine. The issue that I'm having, however, is with my access filters.
I'm using the following code to see if a user is allowed to see the gallery they are trying to access:
def authenticate_viewers!
if user_signed_in? && current_user.can_view?(#gallery)
return true
end
redirect_to root_url,
:notice => "You must have permission to view this gallery."
return false
end
As you can see, can_view? requires the #gallery that I'm setting up in the show method, but a before_filter won't let you access the attributes set up in the method, since it resolves before the method executes. Using an after_filter works, as long as an unauthorized user doesn't try to view the gallery. If it does, I get a DoubleRender error, since after_filter allows the page to render, then tries to redirect.
I just thought that I could perhaps use params[:id] instead of #gallery, though I haven't tried it yet, and ultimately this may be more efficient (passing an integer instead of an object). In any case, is there a way to make my current code work? or is it in my best interest to switch to using the params (if that's even going to work)?
Wow, okay. It's really helpful just to start writing questions here on SO, because as I do, I typically get a brainstorm of how to solve the problem. Instead of using the #gallery object, I just use a Gallery.find(params[:id]) and everything works like a charm. Thank God I don't have to rewrite all my code.

Rails app doesn't see my views

I've on a while on rails now and here's the problem I've been having on and on:
When I create a controller through:
"rails generate controller ControllerName ViewName"
I get everything working as I want but if for some reason I create the controller through:
"rails generate controller ControllerName"
and then just add ViewName.html.erb to the folder inside views that has the same name as my controller things would go wrong.
So the concrete case is me writing:
rails generate controller Subjects list show.
Which creates for me:
1.controllers>subjects_controller.rb
2.views>subjects>list.html.erb
3.views>subjects>show.html.erb
So this whole thing works fine.But as I already said if I need another view; let's say "new" I just add "new.html.erb" next to the other *.html.erb files and an action:
def new
end
to my subjects_controller.rb then it won't work.
The two previous views would keep working but any other "*html.erb" created outside the command line wouldn't.
Is there anywhere else where info about views is being stored?.
I'm a Windows 7 user (32 bit).Rails version=3.0.3. WebServer=WEBrick.
Text editor = E-TextEditor
This is most likely caused by your routes not being correctly configured. So it would be helpful to see the content of your routes.rb
In your case I think the best way to configure the routes is to use the resources mapping:
resources :subjects
This will by default create routing for the standard RESTful actions :index, :show, :edit, :update, :new, :create and :destroy.
For more detailed information about the routing, I would recommend Rails Routing from the Outside In