Rails 3 модель рекурсивных полиморфных комментариев, как сделать перенаправление на самый верхний родитель - PullRequest
1 голос
/ 09 декабря 2011

Я все еще зарабатываю свои полосы в Rails и столкнулся с проблемой, с которой я могу помочь. Я создаю приложение, в котором есть различные модели (истории, фотографии, рисунки и т. Д.), Которые пользователь может комментировать, а также сами комментарии. У меня работает 98-99% функционала, но я застрял при получении перенаправления для перенаправления на самого верхнего родителя (историю, фотографию и т. Д.) После создания комментария.

Моя модель комментария выглядит так:

# /app/models/comment.rb
class Comment < ActiveRecord::Base
  belongs_to :commentable, :polymorphic => true
  has_many :comments, :as => :commentable
end

... У меня есть несколько моделей, которые пользователь может комментировать, например модель истории:

# /app/models/story.rb
class Story < ActiveRecord::Base
  has_many :comments, :as => :commentable
end

Контроллер моих комментариев выглядит следующим образом:

# /app/controllers/comments_controller.rb
class CommentsController < ApplicationController

  def index
    @commentable = find_commentable
    @comments = @commentable.comments
  end

  def new
    @commentable = find_commentable
  end

  def create
    @commentable = find_commentable
    @comment = @commentable.comments.build(params[:comment])
    if @comment.save
      redirect_to :back
    else
      render :action => 'new'
    end
  end

  protected

  def find_commentable
    params.each do |name, value|
      if name =~ /(.+)_id$/
        return $1.classify.constantize.find(value)
      end
    end
    nil
  end

end

... И, конечно, мои маршруты выглядят так:

# /config/routes.rb
resources :comments do
  resources :comments
end

resources :stories do
  resources :comments
end

Конкретная строка, которую мне нужно изменить, - это строка redirect_to :back (все остальное, полиморфизм, рекурсия комментариев и т. Д. Работает нормально). Текущий код работает, как задумано, когда пользователь комментирует историю, но он не идеален, когда пользователь комментирует комментарий, потому что форма для этой функциональности не находится на странице «показа» истории (возможно, так и должно быть?).

То, что я пытался сделать (и, как я подозреваю, могло бы быть решением), - это метод, который находит родительский объект и повторяется, когда этот объект является комментарием. Мои предыдущие попытки сделать это не были чистыми, и мне еще предстоит заставить работать работающий прототип.

Я использовал этот эпизод Railscasts , чтобы основать большую часть моего кода, но redirect_to :id => nil не работает для меня, так как метод создания комментария каким-то образом вызывается, и он приводит к NilClass error, когда он пытается создать комментарии (возможно, что-то не так с моей маршрутизацией, поскольку я не вижу, как действие index вызвало бы создание?).

Итак, эксперты Rails, что я делаю не так? Что мне нужно сделать здесь, чтобы это заработало? Я чувствую, что нахожусь там на 99%, но этот последний 1% сводит меня с ума.

Заранее спасибо ...

Ответы [ 2 ]

1 голос
/ 09 декабря 2011

Решено это ... Это, вероятно, не самый чистый, но он работает:

Сначала я добавил метод в контроллер комментариев ...

def get_master
  @parent = @comment.commentable
  if @parent.respond_to?('commentable_type')
    @comment = @parent
    get_master
  else
    return @parent
  end
end

Затем я изменил свой redirect_to для вызоваэтот метод в контроллере создания.

Ключ понимал, что @ object.respond_to?было то, что мне нужно было сделать, чтобы проверить, определен ли метод.

Вот полный пример того, как он работает: http://t.co/N6WIGzuW

1 голос
/ 09 декабря 2011

Хорошо, я должен был прочитать это пару раз ...

@comment.commentable 

вернет экземпляр Story или любой другой объект, который сделал комментарий.

...