0

I have links in a users page where I keep getting redirected to home page if I'm not the signed in user.

routes.rb

resources :users, only: [:show] do 
  resources :interests, only: [:create]
  member do
    get 'interests'
    get 'likes'
    get 'followers'
    get 'following'
  end  
end

views/users/show.haml

= link_to user_path do
  User
= link_to likes_user_path do
  Likes
= link_to followers_user_path do
  Followers
= link_to following_user_path do
  Following

If I'm viewing my own user page, all links work. But if I'm viewing someone else's page, only the user_path work correctly, but the other links just redirects me to home page as if I can't access it unless I'm the signed in user.

users_controller.rb

class UsersController < ApplicationController
  before_filter :authenticate_user!
  load_and_authorize_resource

  def show
    @user = User.friendly.find(params[:id])
  end
end

I find it odd that I don't even need to have a method for likes, following, and followers in my controller?

Those links are directing to these pages:

views/users/likes.haml

views/users/following.haml

views/users/followers.haml

hellomello
  • 8,219
  • 39
  • 151
  • 297
  • 1
    Try `user_path(@user)`, `likes_user_path(@user)` and so on. I'd recommend creating those methods on UsersController to load the associations. `@likes = @user.likes`... – Alexandre Angelim Dec 29 '15 at 02:31
  • 1
    Also, if you want every user to see any other user's likes, following and followers you should remove `load_and_authorize_resource` or allow everyone to read user attributes on CanCan config. It is likely that you defined on CanCan that a user can only read it's own attributes. – Alexandre Angelim Dec 29 '15 at 02:40

2 Answers2

1

Fix

I can't access it unless I'm the signed in user

The problem is you're calling before_action :authorize_user! on all the users_controller methods. This triggers the Devise user authentication check, which means that only logged-in users are able to view that page.

What you'll want is to limit the authentication to only the actions you want:

#app/controllers/users_controller.rb
class UsersController < ApplicationController
   before_action :authenticate_user, except: [:likes, :followers, :following]
end

This will only apply to the users controller -- interests should allow you, unless you're using authenticate_user! on there.


Misc

I find it odd that I don't even need to have a method for likes, following, and followers in my controller?

Rails 4+ has a built-in mechanism to load views regardless of whether the action is present or not.

--

Rails doesn't need index method in controller defined? (Docs):

By default, controllers in Rails automatically render views with names that correspond to valid routes. For example, if you have this code in your BooksController class:

class BooksController < ApplicationController
end

And the following in your routes file:

resources :books

And you have a view file app/views/books/index.html.erb:

<h1>Books are coming soon!</h1>

Rails will automatically render app/views/books/index.html.erb when you navigate to /books and you will see "Books are coming soon!" on your screen.


Notes

There are some fixes to your syntax:

  1. Routes

Your routes can be DRYed up:

#config/routes.rb
resources :users, only: [:show] do 
  resources :interests, only: [:index, :create] #-> url.com/users/:user_id/interests
  %i(likes followers following).each { |link| get link, on: :member #-> url.com/users/:id/likes }
end
  1. Links

You should use the in-line style of link_to if you've only got a single string to output:

#app/views/users/show.haml
= link_to "User",      user_path(user) #-> this should have a reference like user_path(user)
= link_to "Likes",     likes_user_path(user)
= link_to "Followers", followers_user_path(user)
= link_to "Following", following_user_path(user)
Community
  • 1
  • 1
Richard Peck
  • 76,116
  • 9
  • 93
  • 147
0

This is because of the code in your user_controller

before_filter :authenticate_user!

This code will be executed for every controller actions and will be redirecting you to login page.Just add exceptions for the methods you want access directly without being login. For more details on adding exceptions to methods in Rails please find the bellow SO threads.

1.before_filter with exception for current user

2.How to skip a before_filter for Devise's SessionsController?

Community
  • 1
  • 1
Praveen George
  • 9,237
  • 4
  • 26
  • 53