Вложенная рельсовая ассоциация и перезапущенная нумерация - PullRequest
1 голос
/ 06 января 2012

Если у меня есть вложенный ресурс, например, так:

resources :users
  resources :posts
end

и user has_many posts, можно ли начать нумерацию Rails на основе родительской ассоциации в URL? Например, в настоящее время вложенные ресурсы просто получают идентификатор:

@user.posts.find(params[:id])

Это правильно именует посты, разрешая только посты с @user ... однако, существует ли способ, при котором post_id является независимым? И.Е. Я хочу, чтобы сообщения каждого пользователя начинались с 1, где:

/users/1/posts/1
/users/2/posts/1

На самом деле ссылаются на два разных сообщения?

1 Ответ

6 голосов
/ 06 января 2012

Это может быть довольно много работы, но в основном вы можете сделать это с помощью следующих шагов:

  1. Создайте миграцию, чтобы добавить новый атрибут для хранения определенного количества сообщений пользователя.(Я использовал user_post_id)
  2. Переопределить Post метод to_param, чтобы использовать только что созданное вами новое значение.(Это должна быть строка.)
    • to_param - это метод, который используют помощники url и path.
  3. Создание before_saveфильтр, который фактически увеличивает значение user_post_id для каждого нового сообщения.
  4. Измените все методы контроллера, чтобы найти на user_post_id

    @user = User.find(params[:user_id])
    @post = @user.posts.where(:user_post_id => (params[:id])).first
    
  5. Измените все своиПредставления, которые могут не работать сейчас

Вы можете увидеть источник здесь: Пример URL-адреса пользовательского вложенного ресурса

Код

Миграция:

class AddUserPostIdToPosts < ActiveRecord::Migration
  def change
    add_column :posts, :user_post_id, :integer
  end
end

post.rb:

class Post < ActiveRecord::Base
  before_save :set_next_user_post_id
  belongs_to :user

  validates :user_post_id, :uniqueness => {:scope => :user_id}

  def to_param
    self.user_post_id.to_s
  end

private
  def set_next_user_post_id
    self.user_post_id ||= get_new_user_post_id
  end

  def get_new_user_post_id
    user = self.user
    max = user.posts.maximum('user_post_id') || 0
    max + 1
  end
end

Пара методов контроллера posts_controller.rb:

class PostsController < ApplicationController
  respond_to :html, :xml

  before_filter :find_user

  def index
    @posts = @user.posts.all
    respond_with @posts
  end

  def show
    @post = @user.posts.where(:user_post_id => (params[:id])).first
    respond_with [@user, @post]
  end
  ...
end
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...