Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>There's many different ways to do this, but i tend to think that <strong>you have a design problem</strong> here, so here's how i would do it. </p> <p>I assume from what you said that your associations look like this :</p> <pre><code> __________ ________ | Question |1 *| Answer | | |&lt;-------------------------------| | | |1 * ___________ * 1| | | |&lt;------| Selection |-----------&gt;|________| | | | | | | | |* 1 ________ | | |___________|-----------&gt;| User | | |* 1| | |__________|-------------------------------&gt;|________| </code></pre> <p>This visual representation clearly shows the problem : your <code>Selection</code> model is redundant, as it represents the fact that a question <code>belongs_to</code> a <code>User</code> (which we already know) ; it would not be redundant if there could be multiple selections for each couple of <code>Question / User</code>, but in practice we <strong>want</strong> that selection to be unique for each couple...</p> <p>A <code>belongs_to</code> relation between <code>Question</code> and <code>Answer</code> would achieve the same thing that your <code>Selection</code> model does, and in fact <em>it would do it better</em> because you won't need all the logic to find the right selection, and to ensure it is unique / that the user is the rightfull owner of the question, etc.</p> <p>So here's what i'd do :</p> <ul> <li><p>In the <code>Question</code> model</p> <pre><code>has_many :answers, inverse_of: :question belongs_to :accepted_answer, class_name: :answer, foreign_key: :accepted_answer_id </code></pre></li> <li><p>In the <code>Answer</code> model</p> <pre><code>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 </code></pre></li> <li><p>In your routes</p> <pre><code>resources :questions do member do # we use put because these are update actions put :accept_answer put :clear_accepted_answer end end </code></pre></li> <li><p>In your <code>QuestionsController</code></p> <pre><code>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 </code></pre></li> <li><p>in your view</p> <pre><code> &lt;% if current_user?(answer.question.user) %&gt; &lt;% if answer.accepted? %&gt; &lt;%= link_to "unselect", clear_accepted_answer_question_path( answer.question ), method: :put, remote: true %&gt; &lt;% else %&gt; &lt;%= link_to "select", accept_answer_question_path( answer.question, answer_id: answer.id ), method: :put, remote: true %&gt; &lt;% end %&gt; &lt;% end %&gt; </code></pre></li> </ul>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload