1

質問をしたユーザーが応答のリストから回答を選択できるSOの機能に似た機能を作成することに興味がありますが、コントローラーの観点からクリックイベントを処理する方法にこだわっています。

現在、私はモデルを持ってQuestionhas_many answersます。さらに、それぞれが回答のみを選択できるSelection、回答選択を象徴するモデルを作成しました。Questionhas_one

show質問のアクションの質問とともに、各質問の回答をレンダリングします。私のパーシャル_answerでは、次のロジックを配置したいと思います。この回答は以前に選択されていました)、 prそうでなければ、彼は回答を に保存する回答を「選択」することができました.インスタンス変数に属性を一致または割り当てる方法をしっかりと理解していること)selectionanswer_idanswer_idselectionPOST

  <% if current_user?(answer.question.user) %>
    <% if current_user.selections.where(:answer_id => answer.id) == answer.id %>
      <%= link_to "unselect", selections_path(:selection => {:answer_id => nil}), :method => :post %>
    <% else %>
      <%= link_to "select", selections_path(:selection => {:answer_id => answer.id}), :method => :post %>
    <% end %>
  <% end %>

私の障害はコントローラーにあります。ユーザーが「選択」リンクを介して新しい回答を選択した場合、メソッドを使用して変数を新しいthe createものに割り当てる方法に固執しています。オンクリックイベントの作成方法に関するヘルプやガイドをいただければ幸いです。ありがとう!@selectionanswer_id

4

1 に答える 1

1

これを行うにはさまざまな方法がありますが、ここに設計上の問題があると思う傾向があるので、ここで私が行う方法を示します。

あなたの言ったことから、あなたの関連付けは次のようになると思います:

 __________                                  ________
| Question |1                              *| Answer |
|          |<-------------------------------|        |
|          |1     * ___________ *          1|        |
|          |<------| Selection |----------->|________|
|          |       |           |            
|          |       |           |*          1 ________
|          |       |___________|----------->| User   |
|          |*                              1|        |
|__________|------------------------------->|________|

この視覚的表現は問題を明確に示しています。モデルは冗長です。これは、質問a (既にわかっている)Selectionという事実を表しているためです。の各カップルに対して複数の選択が可能であれば冗長ではありませんが、実際には、その選択が各カップルに対して一意であることを望みます...belongs_toUserQuestion / User

と の間のbelongs_to関係は、モデルと同じことを達成します。実際QuestionAnswerは、正しい選択を見つけて、それが一意であることを確認するためのすべてのロジックを必要としないため、より適切に実行できます。質問の所有者などSelection

だからここに私がしたいことがあります:

  • Questionモデルでは

    has_many   :answers,         inverse_of: :question
    belongs_to :accepted_answer, class_name: :answer, foreign_key: :accepted_answer_id
    
  • Answerモデルでは

    belongs_to :question, inverse_of: :answers
    
    def accepted?
      return false if new_record? 
      question.try( :accepted_answer_id ) == id
      # an alternative is to use question.try( :accepted_answer ) == self
    end
    
  • あなたのルートで

    resources :questions do
      member do 
        # we use put because these are update actions
        put :accept_answer
        put :clear_accepted_answer
      end
    end
    
  • あなたのQuestionsController

    respond_to :js, only: [:accept_answer, :clear_accepted_answer]
    
    def accept_answer
      @question = Question.find( params[:id] )
    
      # ...cue some logic to ensure current_user 
      # has required rights to update the question
    
      if @question.update_attributes( accepted_answer_id: params[:answer_id] )
        # ...render the js that updates your view (for example, 
        # find and replace calling link with an "unselect" one )
      else
        # .. an error has occurred, render an "unprocessable entity" status
      end
    end
    
    
    def clear_accepted_answer
      @question = Question.find( params[:id] )
    
      # ...cue some logic to ensure current_user 
      # has required rights to update the question
    
      if @question.update_attributes( accepted_answer_id: nil )
        # ...render the js that updates your view (for example, 
        # find and replace calling link with a "select" one )
      else
        # .. an error has occurred, render an "unprocessable entity" status
      end
    end    
    
  • あなたの見解では

      <% if current_user?(answer.question.user) %>
        <% if answer.accepted?  %>
          <%= link_to "unselect", 
                      clear_accepted_answer_question_path( answer.question ),
                      method: :put,
                      remote: true %>
        <% else %>
          <%= link_to "select", 
                      accept_answer_question_path( 
                        answer.question, 
                        answer_id: answer.id 
                      ), 
                      method: :put,
                      remote: true %>
        <% end %>
      <% end %>
    
于 2013-01-26T18:19:06.463 に答える