views:

65

answers:

1

I have a simple web app with users and posts. I have an index controller and view that shows a list of the posts in the database. With the list, it shows a "Show" link which links to the specific post.

I am trying to replicate that for users but something is going wrong. I have an index view that shows all the users in the database and I have a "Profile" link which should link to a specific user. (Show action is already being used for users own account) See code below, the User Profile action is the same as the Post Show action but it doesn't work.

# users_controller.rb

  def index
    @users = User.all

    respond_to do |format|
      format.html # index.html.erb
      format.xml  { render :xml => @users }
    end
  end

  def profile
    @user = User.find(params[:id])

    respond_to do |format|
      format.html # show.html.erb
      format.xml  { render :xml => @user }
    end
  end

# posts_controller.rb

  def index
    @posts = Post.all

    respond_to do |format|
      format.html # index.html.erb
      format.xml  { render :xml => @posts }
    end
  end

  def show
    @post = Post.find(params[:id])
    @user = User.find_by_id(@post.user_id)

    respond_to do |format|
      format.html # show.html.erb
      format.xml  { render :xml => @post }
    end
  end

# users/index.html.erb

<h1>Listing All Users</h1>

<table>
  <tr>
    <th>Name</th>
    <th>Email</th>
  </tr>

<% @users.each do |user| %>
  <tr>
    <td><%= link_to user.login, user %></td>
    <td><%=h user.email %></td>
  </tr>
<% end %>
</table>

<br />

I am thinking it may be a problem in my routes. But I can't see anything.

  map.connect ':controller/:action/:id'
  map.connect ':controller/:action/:id.:format'
  map.root :controller => "Home"
  map.resource :account, :controller => "users"
  map.resources :password_resets
  map.resources :users
  map.resource :user_session
  map.root :controller => "user_sessions", :action => "new"
  map.resources :users, :has_many => :posts

When I try go to users/1 I get "No action responded to 1. Actions: create, edit, index, new, profile, show, and update"

+4  A: 

Routes are evaluated from top to bottom. users/1 is getting caught by :controller/:action/:id, not by map.resources :users as you intend. Move these two "default routes" to the bottom of the file.

map.connect ':controller/:action/:id'
map.connect ':controller/:action/:id.:format'
Jonathan Julian
Thanks. That took the error away. Now "<%= link_to user.login, user %>" is linking to the show action. I want it to link to the profile action. Is this a routing issue?
GreenRails
Yep. You need to add the special `profile` action to your route: `map.resources :users, :member => {:profile => :get}`. Then `<%= link_to user.login, user_profile(user) %>`
Jonathan Julian
Thanks for the answer, but unfortunately user_profile(user) gives an error. Although the link /3/profile/ works. Time to look up routes I think!
GreenRails
I solved it with "map.profile 'profile/:id', :controller => 'users', :action => 'profile'"
GreenRails
Oops, should have been `user_profile_path(user)`. Use `rake routes` to see all your named routes based on routes.rb.
Jonathan Julian