0

I have three tables - result, feedback_qs, and feedback_qs_results (join table). Given an existing result and feedback_qs, I want to populate the join table with the result_id, feedback_q_id and the subsequent answer (text_area).

I believe the relationships are correct....

# result.rb
has_many :feedback_q_results
has_many :feedback_qs, :through => :feedback_q_results

# feedback_q.rb
has_many :feedback_q_results
has_many :results, :through => :feedback_q_results

# feedback_q_result.rb
belongs_to :result
belongs_to :feedback_q

I have access to the result_id (result/result.id/feedback) via config/routes.rb below...

resources :results do
  member do
    get 'feedback'
    post 'feedback_create'
  end
end

What would this form look like to populate the join table? Something similar to this (I realize this isn't correct)...? How do I take in the data through the post_controller to populate the join table? Or should it go through another controller?

<%= form_for :result, url: feedback_create_result_path(result), method: :post do |form| %>
  <% for q in FeedbackQ.all %>
  <div class="col field">
    <p>
      <%= form.label q.question_text %>
    </p>
    <%= text_area_tag id: q.id %>
  </div>
  <% end %> 

  <div class="actions">
    <%= form.submit "Submit", class: "btn btn-primary" %>
  </div>
<% end %>

What would my feedback_create method look like? While I've seen several questions regarding rails' many to many relationships and populating join tables, none of those use cases seems to suit my need. Thanks in advance.

Update - My use case is this: user takes an exam (called a result), and they then review the proctor by answering feedback questions. I want to record the feedback in the join table

jtw
  • 11
  • 4
  • Firstly, you'll want to pluralize your `has_many` associations, e.g. `has_many :feedback_q_results` – XML Slayer May 30 '18 at 15:10
  • Really? I always thought models should be singular? Either way, if I'm not mistaken it shouldn't effect functionality..... – jtw May 30 '18 at 15:12
  • The name of the model is singular, yes, such as `FeedbackQ`, but associations are "english-ized". `has_many` is plural, `has_one` and `belongs_to` are singular. – XML Slayer May 30 '18 at 15:35
  • @XMLSlayer. Understood. That makes sense. Updated question. – jtw May 30 '18 at 15:43
  • Did I understand correctly - you want to add some existing feedback_qs to the given result? Or you want to create a new feedback_q for the given result? – Vasilisa May 30 '18 at 15:52
  • Ah, almost, `feedback_q_results` instead of `feedback_qs_results`. Just pluralize at the end. – XML Slayer May 30 '18 at 15:57
  • @Vasilisa - Given an existing result, and a feedback_q, I want to add an entry to the join table, feedback_qs_results – jtw May 30 '18 at 15:58
  • @XMLSlayer - got it. Edited question. – jtw May 30 '18 at 16:01
  • You need to add checkboxes/multi-select with all FeedbackQs. In this case you'll get an array of feedback_qs_ids, and you can just update the given result with its value. Try in console `Result.first.feedback_qs_ids`. Sorry, I can't provide example of code, because I can't remember when I wrote a form without simple_form :) – Vasilisa May 30 '18 at 16:12
  • @Vasilisa The input that will get recorded (besides result_id and feedback_q_id) is the text from the text box, so no need for checkbox or multiselect..... – jtw May 30 '18 at 19:31
  • @XMLSlayer Just a note, I actually found this SO article - https://stackoverflow.com/questions/11590469/rails-naming-convention-for-join-table that says both tables in the join table should be pluralized as well, ie feedback_qs_results – jtw May 30 '18 at 19:59
  • @jtw If we're coming from SQL-land, then yes both names should be plural, but table names aren't necessarily important when defining associations. You can actually define them either way, Rails will figure it out, but I've never seen an association defined with both names being pluralized. – XML Slayer May 30 '18 at 20:32
  • @XMLSlayer I only pluralized the last word in my models. However, in the rails command line, I'm getting the following error - relation "feedback_q_results" does not exist.....see my comments in the answer below....Any idea why rails can't find this relation? – jtw May 30 '18 at 20:39

2 Answers2

0

If your has_many associations are working correctly, then in the rails console you should be able to do:

> result.feedback_qs
=> []

and

> feedback_q.results
=> []

Where result and feedback_q are are Result and FeedbackQ objects, respectively.

To associate a feedback_q to a result, simply:

> result.feedback_qs << feedback_q

This should create a record in the feedback_q_result table. Now, when you do

> result.feedback_qs

It should return the feedback_q record that you just added.

Hula_Zell
  • 1,190
  • 13
  • 13
  • When I entered result.feedback_qs << feedback_q, it gave me the error "relation "feedback_q_results" does not exist".... My table is named feedback_qs_results which explains that......What is odd is that table was named using the "rails g CreateJoinTableResultFeedbackQs" command – jtw May 30 '18 at 19:22
  • @ Hula_Zell, any ideas? – jtw May 30 '18 at 21:09
0

I altered my original models. One issue I ran into was simple naming convention in rails, so I simplified the table names to eliminate that from the equation. New models:

# result.rb
has_many :feedbacks
has_many :questions, :through => :feedbacks

# question.rb
has_many :feedbacks
has_many :results, :through => :feedbacks

# feedback.rb
belongs_to :question
belongs_to :result
validates_uniqueness_of :question_id, scope: :result_id

form in my view:

<%= form_for :result, url: feedback_create_result_path(result), method: :post do |form| %>
    <% Question.all.each do |question| %>
    <div class="col field">
    <p>
        <%= form.label :question, question.question_text %>
    </p>
        <%= hidden_field_tag 'question[][id]', question.id %>
        <%= text_area_tag 'question[][answer]', "", id: "question_" + question.id.to_s, class: "stretch_textarea" %>
    </div>
    <% end %>   

<div class="actions">
    <%= form.submit "Submit", class: "btn btn-primary" %>
</div>

This SO page helped quite a bit as well.

jtw
  • 11
  • 4