I'm creating an an answer model and the query portion of it is saved, however, the anonymous portion of it is not.
This is my answers model
class Answer < ActiveRecord::Base
has_many :comments, dependent: :destroy
belongs_to :question
attr_accessible :anonymous, :answer, :commenter, :votes, :comments_attributes
accepts_nested_attributes_for :comments
end
And this is my form.
<%= form_for([#question, #answer]) do |f| %>
<p>
<%= f.label :answer %>
<%= f.text_area :answer, :cols => "50", :rows => "30"%>
</p>
<p>
<%= check_box_tag(:anonymous)%>
<%= label_tag(:anonymous, "Anonymous")%>
</p>
<p>
<%= f.submit "Submit Answer" %>
</p>
<% end %>
When I check my command prompt for the POST request, initially both answer and anonymous have values, answer may have string "aw;oeigh;aioewhg" and anonymous has value 1. However, when it does the actual create, anonymous gets nil and answer gets "a;oewigh;oih." Why is this
This is my controller if it's any help. Thanks!
def create
#answer = #question.answers.new(params[:answer])
if #answer.anonymous == true
#answer.commenter = "Anonymous"
else
#answer.commenter = current_user.username
end
if #answer.save
redirect_to question_path(#question)
else
redirect_to questions_path
end
end
it may be because your params anonymous is not within answer
try
f.check_box :anonymous
instead
<%= check_box_tag(:anonymous)%>
Related
Can't mass-assign protected attributes: answer. (Using Rails3)
I'm not sure why it's not allowing me to do so as I have my nested attributes accessible.
This is my answer model
class Answer < ActiveRecord::Base
has_many :comments, dependent: :destroy
belongs_to :question
attr_accessible :anonymous, :answer, :commenter, :votes, :comments_attributes
accepts_nested_attributes_for :comments
end
This is my comments model
class Comment < ActiveRecord::Base
belongs_to :answer
attr_accessible :anonymous, :comment, :writer, :votes
end
I'm failing at this form on the view
<%= form_for([#answer, #comment]) do |f| %>
<p>
<%= f.label :comment %>
<%= f.text_area :comment, :cols => "50", :rows => "30"%>
</p>
<p>
<%= f.submit "Submit Comment" %>
</p>
<% end %>
This is my function in my commentsController that is apparently causing the error
def create
#answer = Answer.find(params[:answer_id])
#comment = #answer.comments.new(params[:comment])
#comment.save
redirect_to question_path(#answer)
end
Your view code is not technically right. You need to use fields_for:
<%= form_for([#answer, #comment]) do |f| %>
<p>
<%= f.fields_for :comments do |u| %>
<%= u.label :comment %>
<%= u.text_area :comment, :cols => "50", :rows => "30"%>
<% end %>
</p>
<p>
<%= f.submit "Submit Comment" %>
</p>
<% end %>
you may also need to remove #comment from the form_For helper. In fields_For, you might need to user :comment or possibly even #comment.
If you are using rails 4, then you will also have a problem with strong parameters: http://edgeapi.rubyonrails.org/classes/ActionController/StrongParameters.html
I'm trying to save the comment text section of a comment and it won't save for some reason.
I'm checking my server outputs, and the comment attribute is set, but when actually saved, it turns out as NIL.
Originally it has "comment"=>{"comment"=>"hello dude"}, "commit"=>"Sbmit Comment"
But in the saving it saves NIL.
Here's my form for comments
<div class="container">
<% if user_signed_in? %>
<%= form_for([#answer, #comment]) do |f| %>
<p>
<%= f.label :comment %>
<%= f.text_area :comment, :cols => "50", :rows => "30"%>
</p>
<p>
<%= f.submit "Submit Comment" %>
</p>
<% end %>
<% else %>
<p> <em>You must be signed in to comment</em> </p>
<% end %>
</div>
Here's my comments controller
class CommentsController < ApplicationController
def create
#answer = Answer.find(params[:answer_id])
#comment = #answer.comments.new(params[:comments])
#comment.writer = current_user.username
#comment.save
redirect_to question_path(#answer)
end
end
And here's my model.
class Comment < ActiveRecord::Base
belongs_to :answer
attr_accessible :anonymous, :comment, :writer, :votes
end
Heres my answers model
class Answer < ActiveRecord::Base
has_many :comments, dependent: :destroy
belongs_to :question
attr_accessible :anonymous, :answer, :commenter, :votes, :comments_attributes
end
Any ideas?
EDIT: I've used params[:comment], however, it says I cannot mass assign attributes to answer, even though answer has attr_accessible: :comments_attributes
In this line #comment = #answer.comments.new(params[:comments]) change :comments to :comment
You are trying to save with params[:comments] in your controller but what is being passed would respond to params[:comment]
Models: Jobs, Applications, Questions, Answers
Jobs has_many questions
has many Applications
Applications has_many answers
belongs_to :job
Questions
has_one :answer
belongs_to :job
In the Application view, I would like to create a view that lists all the questions a particular job has, and gives the corresponding field for the answers.
Right now, I'm able to do that in a bit of a hacked way.
I think the best way to do it is to run 2 simultaneous loops, one of which is an array of questions, #questions, and the other one, which is fields_for :answers
Then, in the fields_for tag, I could provide the question.id, as well as the question.content
Is there a way to do this?
This is my current strategy
<%= form_for [#job, #application] do |f| %>
<%= render 'shared/error_messages', object: f.object %>
<% #job.questions.each do |question| %>
<%= f.fields_for :answers, question do |a| %> #This is the hacked part
<%= a.label :content, question.content %>
<%= a.text_area :content, value: "" %>
<%= a.hidden_field :question_id, value: question.id %>
<% end %>
<% end %>
<%= f.submit "Submit the application", class: "button" %>
<% end %>
What I'm doing there is passing the question object as the object for the fields_for tag.
This is my controller ->
def new
job = params[:job_id]
#application = Application.build(job)
redirect_to jobs_path, :notice => "You've already applied to this job! Check out some more" if has_job(current_user,#job)
end
And Application Model ->
class Application < ActiveRecord::Base
belongs_to :job
belongs_to :user
validates :job_id, presence: true
validates :user_id, presence: true
has_many :questions, through: :job
has_many :answers, dependent: :destroy
accepts_nested_attributes_for :answers, allow_destroy: true
def self.build(job_id)
application = self.new
job = Job.find(job_id)
job.questions.count.times do
application.answers.build
end
application
end
end
I found this --> http://rosettacode.org/wiki/Loop_over_multiple_arrays_simultaneously#Ruby ,
But I'm not sure if that can be implemented with a fields_for
Looks like there's a problem with your associations. It seems you want a Job to be able to have many applications and its own set of questions. Each application will then have a set of answers with each answer corresponding to one question in the Job posting. Reflecting this, you would have the ff associations:
Job has_many :questions
has many :applications
Application has_many :answers
belongs_to :job
Question has_many :answer
belongs_to :job
Answer belongs_to :application
belongs_to :question
Then we do this in the model:
def build_answers
job.questions.each do |question|
application.answers.build(question_id: question.id)
end
end
And in the controller:
def new
#application = Application.new(job_id: params[:job_id])
#application.build_answers
redirect_to jobs_path, :notice => "You've already applied to this job! Check out some more" if has_job(current_user,#job)
end
That way, your view would look simpler:
<%= form_for #application do |f| %>
<%= f.hidden_field :job_id, value: f.object.job_id %>
<%= render 'shared/error_messages', object: f.object %>
<%= f.fields_for :answers do |a| %>
<% question = a.object.question %>
<%= a.label :content, question.content %>
<%= a.text_area :content %>
<%= a.hidden_field :question_id, value: question.id %>
<% end %>
<%= f.submit "Submit the application", class: "button" %>
<% end %>
Hope that helps!
I'm trying to make a dynamic form of questions and answers, like so:
Question _______
Answer _______
Question _______
Answer _______
I can't figure out how to loop through the two resources as alternating pairs. I have tried this:
<%= semantic_fields_for [#question, #answer] do |h, i| %>
<%= f.inputs :for => #question do |h|%>
<%= h.input :question %>
<% end %>
<%= f.inputs :for => #answer do |i|%>
<%= i.input :answer %>
<% end %>
<% end %>
But it gives me the error "Undefined method `model_name' for Array:Class."
My controller:
def new
#post = Post.new
#question = #post.questions.new
#answer = #question.build_answer
respond_to do |format|
format.html
end
end
And my models:
class Post < ActiveRecord::Base
has_many :questions
has_many :answers
end
class Question < ActiveRecord::Base
belongs_to :post
has_one :answer
end
class Answer < ActiveRecord::Base
belongs_to :question
belongs_to :post
end
So I don't personally use formtastic but I understand it follows similar lines to simple_form. Your error is coming from trying to pass an Array to semantic_fields_for which only takes a single object:
<%= semantic_form_for #questions do |q| %>
<%= q.input :question %>
<%= q.semantic_fields_for #answer do |a| %>
<%= a.inputs :answer %>
<% end %>
<%= q.actions %>
<% end %>
Don’t forget your models need to be setup correctly with accepts_nested_attributes_for
class Question < ActiveRecord::Base
belongs_to :post
has_one :answer
accepts_nested_attributes_for :answers
end
You'll want to check out the formtastic docs at https://github.com/justinfrench/formtastic
That should get your form showing correctly in the view but you'll need to add some more to your questions controller to make sure it saves the answers (someone correct me if I'm mistaken).
Also just so it's clear do your Questions and Answers tables really have a question and answer column? If the columns are actually something like :body you'll want to replace the relevant symbols in the above code.
I think what you need is exactly what is described in these railcasts:
Nested Model Form Part 1
Nested Model Form Part 2
I think you should also refactor a bit, Posts should not have questions. You might notice a little difference from the railcasts but that's because you have only one answer per question whereas in the railcasts a question has many answers. In the part 2 it shows how to add AJAX calls to add/remove questions and answers (probably you won't need this if you only have one answer).
Mandatory reading so you have a better understanding of associations and how nested attributes work:
A Guide to Active Record Associations
Active Record Nested Attributes
And this is an example that will probably work, with some minimum tweaking. I haven't used semantic fields, just the standard form builder.
class Post < ActiveRecord::Base
has_many :questions
accepts_nested_attributes_for :questions, :reject_if => lambda { |a| a[:content].blank? }, :allow_destroy => true
end
class Question < ActiveRecord::Base
belongs_to :post
has_one :answer, :dependent => :destroy
accepts_nested_attributes_for :answers, :reject_if => lambda { |a| a[:content].blank? }, :allow_destroy => true
end
class Answer < ActiveRecord::Base
belongs_to :question
end
# posts_controller.rb
def new
#post = Post.new
# lets add 2 questions
2.times do
question = #post.questions.build
question.build_answer
respond_to do |format|
format.html
end
end
# views/posts/_form.html.erb
<%= form_for #post do |f| %>
<%= f.error_messages %>
<p>
<%= f.label :name %><br />
<%= f.text_field :name %>
</p>
<%= f.fields_for :questions do |builder| %>
<%= render "question_fields", :f => builder %>
<% end %>
<p><%= f.submit "Submit" %></p>
<% end %>
# views/posts/_question_fields.html.erb
<p>
<%= f.label :content, "Question" %><br />
<%= f.text_area :content, :rows => 3 %><br />
<%= f.check_box :_destroy %>
<%= f.label :_destroy, "Remove Question" %>
</p>
<%= f.fields_for :answers do |builder| %>
<%= render 'answer_fields', :f => builder %>
<% end %>
# views/posts/_answer_fields.html.erb
<p>
<%= f.label :content, "Answer" %>
<%= f.text_field :content %>
<%= f.check_box :_destroy %>
<%= f.label :_destroy, "Remove" %>
</p>
I have 3 models:
User: has_many :comments
Video: has_many :comments
Comment: belongs_to :video, :user
videos/show.html.erb
<%= form_for(#comment, :method => :post ) do |f| %>
<%= f.text_area :body %>
<%= f.hidden_field :video_id, :value =>"4" %>
<%= f.submit "submit" %>
<% end %>
comments_controller
def create
#comment = Comment.new(params[:comment].merge(:user_id => current_user.id))
#comment.save
end
How can i check existence of Video before i create a comment?
This should be present as a validation in your Comment model.
class Comment < ActiveRecord::Base
validates_presence_of :video