Rails3嵌套路由问题

时间:2010-07-20 14:07:53

标签: ruby-on-rails routing rest ruby-on-rails-3

我想为用户创建一种机制来跟踪其他喜爱的用户,类似于SO最喜欢的问题。我正在使用Rails 3.0测试版。

为此,我有一个User-Favorite HABTM关系,它按预期工作:

class User < ActiveRecord::Base
  has_and_belongs_to_many :favorites, :class_name => "User", :join_table => "favorites", :association_foreign_key => "favorite_id", :foreign_key => "user_id"
end

收藏夹控制器只需要7种RESTful方法中的3种来管理用户的收藏夹:

class FavoritesController < ApplicationController

  # GET /favorites
  # GET /favorites.xml
  def index

    @user = User.find(params[:user_id])
    @favorites =  @user.favorites.joins(:profile).order("last_name,first_name")

    ...

  end

  def create

    @favorite = User.find(params[:id])
    current_user.favorites << @favorite

    ...

  end

  def destroy

    @favorite = User.find(params[:id])
    current_user.favorites.delete(@favorite)

    ...

  end

end

Routes.rb文件包含路由指令:

resources :users, :except => :destroy do
  resources :favorites, :only => [:index,:create,:destroy]
end

生成这些用户最喜欢的路线:

GET    /users/:user_id/favorites(.:format)            {:controller=>"favorites", :action=>"index"}
user_favorites POST   /users/:user_id/favorites(.:format)            {:controller=>"favorites", :action=>"create"}
user_favorite DELETE /users/:user_id/favorites/:id(.:format)        {:controller=>"favorites", :action=>"destroy"}

在用户的显示视图中,用户(@user)可以使用图像链接切换为收藏夹,按预期工作:

<% if [test if user is a favorite] %>

    # http://localhost:3000/favorites/destroy/:id?post=true
    <%= link_to image_tag("favorite.png", :border => 0), :controller => :favorites, :action => :destroy, :post=>true, :id => @user %>

<% else %>

    # http://localhost:3000/favorites/create/:id?post=true
    <%= link_to image_tag("not-favorite.png", :border => 0), :controller => :favorites, :action => :create, :post=>true, :id => @user %>

<% end %>

但是,在current_user最喜欢的索引视图中,link_to每个收藏的用户:

# http://localhost:3010/users/4/favorites/3?post=true
<%= link_to image_tag("favorite.png", :border => 0), :controller => :favorites, :action => :destroy, :id => favorite, :post=>true %>

生成错误,内容如下:

没有路线匹配“/ users / 4 / favorites / 3”

问题:

  1. 我是否正确指定了路由?似乎创建和销毁路线只需要收藏夹的ID,因为收藏夹的“所有者”始终是current_user。
  2. 如果我只是在Show视图中引用Controller / Action,我是否还需要创建/销毁路由?
  3. 为什么索引视图中的link_to无法正常工作?
  4. 是否可以对整体方法进行任何改进?

2 个答案:

答案 0 :(得分:3)

您的路由看起来很好。

我认为你的link_to有问题。首先,RESTful方式不是使用:controller和:action参数指定URL。正确的方法是使用生成的URL方法,例如user_favorite_path。此外,您需要在定位destroy操作时指定:method参数。这就是我认为link_to应该是这样的:

<%= link_to image_tag("favorite.png", :border => 0), user_favorite_path(@user, @favorite), :method => :delete %>

我认为它说没有路由匹配该URL的原因是因为你没有将:method指定为:delete。

答案 1 :(得分:0)

在你的rake路由输出中,所需的参数是:user_id not:id,所以你需要在你的link_to调用中发送它。