foreign key needs index contraint
bin/rails g model answer body:text question:references
# is called: question_id (Rails convention)
# index: true -> will automatically create an index on the `question_id` field
# foreign_key: true -> will automatically create a foreign key constraint
# for the `question_id` field
class Question < ActiveRecord::Base
has_many :answers, dependent: :destroy
q = Question.last
a = Answer.new(body: "my awesome answer")
a.question = q
a.question_id = q.id
a.save
q.destroy will first delete the answer associated with question then will delete the question
q = Question.last
q.answers.create(body: "Hello")
a = q.answers.new(body: 'HellO')
a.save
Answer.create(body: "hello", question: q)
q.answers
resources :questions do get :search, on: :collection patch :mark_done, on: :member post :approve
resources :answers resources :answers, only[:create, :destroy]
if you define resources as nested rails will define all answers routes prepended with the next routes
Steps
in your controller you must define an instance variable
we can user the form after overiding the url parameter.The downside to i tis that it wont work for "edit" situation. This will work in "create" situation. So we can't reuse it when we decide to implement editing answers.
<%= form_for @answer, url: question_asnwers_path(@question) do |f|%>
<% end %>
This is the prefered approach
<%= form_for [@quetion, @answer] do |f| %>
passing an array for "form_for" is a better approach for creating nested resources. This approach will work for both new/ edit situations. so if @answer is not persisted it will send a Post request to question_answers_path(@question). And if @answer is persisted it will send a PATCH request to question_answer_path(@question, @answer)
bin/rails g controller answers
in the answers controller
def create @question = Question.find params[:question_id] answer_params = params.require(:answer).permit(:body) @answer = Answer.new answer_params @answer.question = @question @answer.save render json: params end
adding this will mkae sure that an answer's body is unique for a given question. This means you cant submit the same answer body twice for the same question but you can submit the same answer body for two different questions.
validates :body, presence:true, uniqueness: {scope: :question_id}
def create @question = Question.find params[:question_id] answer_params = params.require(:answer).permit(:body) @answer = Answer.new answer_params @answer.question = @question if @answer.save redirect_to question_path(@question), notice: "asnwer created!" else render "/questions/show"
end
<%= @answer.errors.full_messages.join(", ") %>
<%= @question.answers.each do |ans| %> <%= ans.body %> <%= link_to "DELETE", question_answer_path(@question, ans), method: :delete, data: {confirm: "Are you sure?"} %>
<%end%>
def destroy
answer = Answer.find params[:id] answer.destroy redirect_to question_path(params[:question_id]) end