Как получить 1-й вложенный объект в контроллер вложенных объектов 2-го уровня?

#ruby-on-rails #partial-views

#ruby-on-rails #частичные представления

Вопрос:

У меня есть символьная модель, в которой есть страница показа. На странице показа у меня есть цикл комментариев, которые динамически генерируются с помощью partial . В этом частичном комментарии у меня есть еще один частичный для голосов, который содержит кнопки голосования. Естественно, я хочу разрешить голоса в комментариях.

Я не уверен, как получить объект комментария в контроллер голосов (или модуль VotesController, в зависимости от реализации) для создания голосования.

Получение идентификатора объекта character для контроллера голосов достаточно просто, поскольку фактическим представлением является страница отображения символов, но получение идентификатора конкретного комментария, который генерируется из partial, путем нажатия кнопки голосования в partial, которая вложена в comments partial, заставляет меня рисовать пробел длясинтаксис доступа к этому комментарию.

(Я использую acts_as_votable для голосования и acts_as_commentable для комментариев.)


app/views/characters/show.html.haml

 = render partial: 'comments/comment', collection: @comments, as: :comment
  

app/views/comments/_form.html.haml

 .comment{ :id => "comment-#{comment.id}" }
  %hr

  = render partial: 'votes/vote_comment'

  %h4
    #comment body
  

приложение / просмотры / голоса /_vote_comment.html.haml

 .vote-comment-buttons
  = link_to image_tag("upvote.png"), votes_upvote_path(), method: :post, remote: true
  = link_to image_tag("downvote.png"), votes_downvote_path(), method: :post, remote: true
  

app/controllers/votes.html.haml

 VotesController < ApplicationController

  def upvote
    # Need the specific comment or comment id whose vote button was clicked.
  end

  def downvote
    # Need the specific comment or comment id whose vote button was clicked.
  end

end
  

Ответ №1:

Ну, вот основные советы:

  1. Вы не можете передавать объекты ruby через HTTP, но вы можете передавать id и type из них создавать их в своем контроллере.
  2. Даже когда вы вводите что-то вроде comment_path(comment) , только id этот комментарий передается вашему действию. Это легко проверить, наблюдая за вашим кодом действия (он должен содержать что-то вроде Comment.find(params[:id]) ).
  3. Передача любого желаемого количества дополнительных параметров может быть выполнена, просто предоставив их вашим помощникам по маршруту, например: some_voting_path(commentable_id: 14, commentable_type: 'character') .
  4. Вы можете получить доступ к этим параметрам внутри вашего действия с params['commentable_type'] помощью или любых значений, которые вы передаете со своим URL. В случае, если вы следуете передаче id и type подходу, вы должны быть в состоянии выполнить некоторое метапрограммирование:

     def upvote_method
      model = params[:commentable_type].camelize.constantize # => e.g., Post
      object = model.find(params[:commentable_id]) # => post object
      # here goes your inner logics
    end
      
  5. Имейте в виду, что в случае, если вы отправляете свой запрос с помощью GET метода, эти параметры будут показаны в URL вашего браузера. Однако вы не должны использовать GET его здесь для своих целей, поскольку голосование изменяет состояние объектов в вашей базе данных.