Я хотел бы создать механизм, позволяющий пользователю отслеживать других любимых пользователей, аналогично любимым вопросам SO. Я использую бета-версию Rails 3.0.
Для этого у меня есть отношение Пользователь-Любимый 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
Контроллеру избранного нужно только 3 из 7 методов RESTful для управления избранным пользователем:
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 %>
Однако в избранном представлении индекса текущего_пользователя ссылка_ для каждого избранного пользователя:
# 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 %>
генерирует ошибку, которая гласит:
Нет совпадений маршрутов "/ пользователи / 4 / избранное / 3"
Вопросы:
- Правильно ли я указал мой маршрут? Похоже, что для создания и уничтожения маршрутов потребуется только идентификатор избранного, поскольку «владельцем» избранного всегда является current_user.
- Если я просто ссылаюсь на Controller / Action в представлении Show, нужно ли мне вообще создавать / уничтожать маршруты?
- Почему link_to в индексном представлении не работает правильно?
- Есть ли какие-либо улучшения, которые можно внести в общий подход?