simple_form association not working as expected - ruby-on-rails

I have a simple_form that is building my form for ResponseSet. A response set is basically collection of responses to a questionnaire (which has_many questions). A question can have many answers. (It's complicated, I know). When attempting to render out the radio buttons for answers to a particular question, none of the radio buttons get selected even though there are answers related to this response. Changing the as: to :check_boxes seems to work correctly. Is this a bug w/ SimpleForm?
= simple_form_for #response_set do |rs|
= rs.simple_fields_for :responses do |r|
- if r.object.question.class <= Question::SingleChoice
= r.association :answers, as: :radio_buttons, collection: r.object.question.answers, label_method: :text, label: false
response_set.rb
class ResponseSet < ActiveRecord::Base
has_many :responses
accepts_nested_attributes_for :responses
end
response.rb
class Response < ActiveRecord::Base
belongs_to :question
has_and_belongs_to_many :answers
belongs_to :response_set
has_many :questions,
through: :answers
accepts_nested_attributes_for :answers
end
questionnaire.rb
class Questionnaire < ActiveRecord::Base
has_many :response_sets
end
answer.rb
class Answer < ActiveRecord::Base
has_many :responses
belongs_to :question
end
question.rb
class Question < ActiveRecord::Base
has_many :responses,
through: :answers
has_many :answers
end

Try adding a :selected option to the association. For example:
= r.association :answers,
as: :radio_buttons,
collection: r.object.question.answers,
label_method: :text,
label: false,
selected: r.object.question.answers.select {|ans| ans.responses.any? }
Also, if you need to build a lot of questionnaires/surveys (especially if they're complicated), I'm a huge fan of the surveyor gem, even though their default CSS is ugly.

Related

Rails: Passing nested attributes to vue.js

I have a Survey model
class Survey < ApplicationRecord
has_many :questions, dependent: :destroy
accepts_nested_attributes_for :questions, allow_destroy: true
belongs_to :user
end
And Quesiton model which is nested to "survey" as below;
class Question < ApplicationRecord
enum qtype: [:multiple_choice, :check_boxes, :short_answer]
belongs_to :survey
has_many :options
accepts_nested_attributes_for :options, allow_destroy: true
end
And option model connected to question as nested.
class Option < ApplicationRecord
belongs_to :question
end
Parameters in my surveys_controller:
def survey_params
params.require(:survey).permit(:name, questions_attributes:[:id, :title, :qtype, :_destroy, options_attributes:[:id, :otext, _destroy]])
end
It is working clear Without Vue.js implementing.
I want to use vue.js for making dynamic form.
What should i do passing do form all nested attributes Without using 'gon' gem
also which json file should i create with jbuilder?
Thanks

Mass edit (create/destroy) many2many relation on Rails

I'm stucked in the way to do this task on Rails 5.
I need to "mass" edit a relation between a Project and it's Members
In the UI, I open a popup with a certain list of members (a list of User) and those member have or have not belongs to the Project (check the relations down here).
I need to have the ability to mark some of them (who not belongs to) or unmark others (who belongs to) with checkbox's and "save" the form and create/delete the relations.
For the record I have this models
// project.rb
class Project < ApplicationRecord
has_many :memberships, dependent: :destroy, class_name: 'ProjectMember'
has_many :members, through: :memberships, class_name: 'User', source: :user
end
// project_member.rb
class ProjectMember < ApplicationRecord
belongs_to :user
belongs_to :project
end
// user.rb
class User < ApplicationRecord
has_many :project_members
has_many :projects, through: :project_members
end
I'm kinda new on Rails and I'm really stucked in the way to create the forms (using SimpleForms) and how to edit the relation.
What's the correct approach? I tried to find over the web without success :(
I hope my question it's clear enough :)
I think the helpers you want are included in the gem cocoon : https://github.com/nathanvda/cocoon
Using this gem, your view for the project edition would look like this :
projects/_form
= simple_form_for #project do |f|
-# your project fields...
%h3 Members
#members
= f.simple_fields_for :members do |member|
= render 'member_fields', f: member
.links
= link_to_add_association 'add member', f, :members
= f.submit
projects/_member_fields
.nested-fields
= f.association :user
= link_to_remove_association "remove user from project", f
Edit : I focused on the view part, but before that, in the model, you have to accept nested attributes from forms :
class Project < ApplicationRecord
has_many :memberships, dependent: :destroy, class_name: 'ProjectMember'
has_many :members, through: :memberships, class_name: 'User', source: :user
accepts_nested_attributes_for :members, reject_if: :all_blank, allow_destroy: true
end
There's also a bit of work to do in the controller to permit the nested attributes.
def project_params
params.require(:project).permit(:name, :description, members_attributes: [:id, :user_id, :_destroy])
end

Rails Checking if One Array is in Another

I have five models: Course, Lesson, Question, Answer and User.
What I'm trying to do is determine if the User has Answers for all of the Questions in a Lesson (so I can put "Done" next to the lesson in the view if this is the case).
My models:
class Course < ActiveRecord::Base
has_many :lessons, dependent: :destroy
has_many :questions, :through => :lessons
has_many :users, through: :purchases
end
class Lesson < ActiveRecord::Base
belongs_to :course
has_many :questions, dependent: :destroy
has_many :answers, through: :questions
end
class Question < ActiveRecord::Base
belongs_to :lesson
belongs_to :course
has_many :answers, dependent: :destroy
end
class Answer < ActiveRecord::Base
belongs_to :question
belongs_to :user
end
class User < ActiveRecord::Base
has_many :answers
has_one :author
has_many :courses, through: :purchases
end
What I tried to do was to check if a Lesson's Questions were in the Questions the User Answered, but the includes? line doesn't seem to be working the way I want.
in my controller, I have:
#lessons = #course.lessons
#answers = current_user.answers
#questions = Question.where(:id => #answers.map(&:question_id))
in my view, I have:
<% #lessons.each do |lesson| %>
<% lesson_questions = lesson.questions %>
<%= user_questions = #questions.where("lesson_id = ?", lesson.id)%>
<% if user_questions.include?(lesson_questions)%>
Done!
<% end %>
<% end %>
I'm not sure if this is the cause, but I noticed the lesson_questions are #<Question::ActiveRecord_Associations_CollectionProxy:0x9c49698>
While the user_questions are: #<Question::ActiveRecord_Relation:0x9c48330>
I'm wondering, (a) how I accomplish my objective of finding the Lessons with all of the Questions answered, and (b) if there's a more efficient way to do this. Thanks!
Problem
You can't check if an array includes another array just like this:
user_questions.include?(lesson_questions)
You need to check if each element from lesson_questions is included in the user_questions.
Try these instead:
Solution: 1
lesson_questions.all? { |lq| user_questions.include?(lq) }
This should return true if all the lesson_questions are included in the user_questions.
Solution: 2
(lesson_questions - user_questions).empty?

Rails 4 has_many through - Cannot modify association

I have DayItem model which has one SchoolProgram which has many seminars.
class DayItem < ActiveRecord::Base
has_one :school_program, dependent: :destroy
has_many :seminars, through: :school_program
accepts_nested_attributes_for :school_program
accepts_nested_attributes_for :seminars, reject_if: :all_blank
end
class SchoolProgram < ActiveRecord::Base
belongs_to :day_item
has_many :seminars, dependent: :destroy
accepts_nested_attributes_for :seminars, allow_destroy: true, reject_if: :all_blank
end
class Seminar < ActiveRecord::Base
belongs_to :school_program
end
I am using cocoon gem for dynamic nested forms as follows.
_form.html.haml:
= simple_form_for [#day, #day_item] do |f|
= f.input :start_time
= f.simple_fields_for :school_program do |form|
= form.input :school
= form.simple_fields_for :seminars do |seminar|
= render 'seminar_fields', :f => seminar, :parent => form
.links
= link_to_add_association 'add seminar', form, :seminars
_seminar_fields.html.haml:
.nested-fields.well.well-compact
.form-inline
= f.input :name
= link_to_remove_association "remove seminar", f
But when I try to add a seminar I get following exception.
 ActiveRecord::HasManyThroughCantAssociateThroughHasOneOrManyReflection in Etm::DayItemsController#update
Cannot modify association 'DayItem#seminars' because the source reflection class 'Seminar' is associated to 'SchoolProgram' via :has_many.
Any help is appreciated.
Circular reference in relationships (source reflection)
There may be more than one issue here, but the first one that should be addressed is that your relationship for Seminars creates a circular reference. It is declared in a has_many in DayItem and then as a has_one on SchoolProgram, which itself belongs to the parent class DayItem. Please try the change below to our DayItem model. Leave the other models as they are, and let me know how that goes.
class DayItem < ActiveRecord::Base
has_one :school_program, dependent: :destroy
accepts_nested_attributes_for :school_program
end

Best approach for creating a polling app in Rails

My models:
class Poll < ActiveRecord::Base
validates_presence_of :title
validates_presence_of :description
has_many :questions, dependent: :destroy
has_many :responses, through: :questions
accepts_nested_attributes_for :questions, reject_if: lambda { |a| a[:title].blank? }, allow_destroy: true
end
class Question < ActiveRecord::Base
belongs_to :poll
has_many :answers, dependent: :destroy
has_many :responses, through: :answers
accepts_nested_attributes_for :answers, reject_if: lambda { |a| a[:content].blank? }, allow_destroy: true
end
class Answer < ActiveRecord::Base
belongs_to :question
has_many :responses
end
class Response < ActiveRecord::Base
belongs_to :answer
end
When you go to /polls/.:id it shows the poll with its corresponding questions and each question with its corresponding answers.
I've been playing around with this answer but I don't know what to do from there. I want whomever I send a poll link (/polls/.:id) to to be able to answer that poll. The method described in the answer linked before creates a form for each question.
I'd check out the documentation on rails views here:
http://guides.rubyonrails.org/action_view_overview.html
There is tons of documentation on how to access and transport data with various form elements.

Resources