So there is a plethora of questions about the "uninitialized constant" error, and it's almost always due to an incorrectly specified association (e.g. plural model names instead of singular, incorrectly writing your association inside the model, etc). My models and form look spotless, so maybe this is something new (or I'm blind)?
A "user" has one "move". A "move" has many "neighborhood_preferences", and through this, many "neighborhoods".
Models:
class User < ActiveRecord::Base
has_one :move
accepts_nested_attributes_for :move, allow_destroy: true
end
class Move < ActiveRecord::Base
belongs_to :user
has_many :neighborhood_preferences
has_many :neighborhoods, through: :neighborhood_preferences
accepts_nested_attributes_for :neighborhood_preferences, allow_destroy: true
end
class NeighbhoodPreference < ActiveRecord::Base
belongs_to :neighborhood
belongs_to :move
end
class Neighborhood < ActiveRecord::Base
belongs_to :city
has_many :neighborhood_preferences
has_many :moves, through: :neighborhood_preferences
end
View:
<%= simple_form_for(#user, :html => { class: :form } ) do |u| %>
<%= u.fields_for :move do |m| %>
<div>
<%= m.label :start_date %>
<%= m.date_field :start_date %>
</div>
<div>
<%= m.label :end_date %>
<%= m.date_field :end_date %>
</div>
<div>
<%= m.label :min_price %>
<%= m.text_field :min_price %>
</div>
<div>
<%= m.label :max_price %>
<%= m.text_field :max_price %>
</div>
<%= m.association :neighborhood_preferences %>
<% end %>
<%= u.submit "Save Changes" %>
<% end %>
There is a typo in class name NeighbhoodPreference.
Related
I have two models in my app: "WorkPost" and "Contacts".
WorkPost
class WorkPost < ActiveRecord::Base
has_one :contacts
end
Contacts
class Contacts < ActiveRecord::Base
belongs_to :work_post
end
In my controller's new method I do:
def new
#work_post = WorkPost.new
#work_post.contacts
end
And in view I create form:
<%= form_for(#work_post) do |f| %>
<div class="field">
<%= f.label 'Vacation' %><br>
<%= f.text_field :post_title, :placeholder => 'Vacation here' %>
</div>
<div class="field">
<%= f.label 'Vacation description' %><br>
<%= f.text_area :post_body, :placeholder => 'Vacation description here' %>
</div>
<% f.fields_for :contacts do |cf| %>
<div class="field">
<%= cf.label 'Email' %><br>
<%= cf.text_field :emails, :placeholder => 'Email here' %>
</div>
<% end %>
<div class="actions">
<%= f.submit "Post vacation", :class => 'btn_act' %>
</div>
<% end %>
But it seems like line <% f.fields_for :contacts do |cf| %> doesn't work.
Everything is rendered fine but email field.What I am doing wrong?
The problem is with this line
<% f.fields_for :contacts do |cf| %>
which should be
<%= f.fields_for :contact do |cf| %>
Also, the class name for the model and the association name for has_one/belongs_to should be singular.
#work_post.rb
class WorkPost < ActiveRecord::Base
has_one :contact #should be singular
end
#contact.rb
class Contact < ActiveRecord::Base #should be singular
belongs_to :work_post
end
Also, notice the change :contacts to :contact, as it is a has_one association.
Update:
Also, try the below changes
Include accepts_nested_attributes_for :contact in work_post.rb model
#work_post.rb
class WorkPost < ActiveRecord::Base
has_one :contact
accepts_nested_attributes_for :contact
end
Change the new method to below
def new
#work_post = WorkPost.new
#work_post.build_contact
end
I'm trying to build a nested form for a survey and having problems with my params hash missing values from within the fields_for block.
I have the following models. The way the app works is that an admin creates a MiniPost and its MiniPostQuestions. Then a client creates a new MiniPostSurvey using one of the MiniPosts. The client then emails out SurveyInvites to users. When a user responds, a new SurveyResponse is created, along with a new QuestionAnswer for each MiniPostQuestion in the survey.
class MiniPost < ActiveRecord::Base
has_many :mini_post_questions
has_many :question_answers, through: :mini_post_questions
has_many :mini_post_surveys
belongs_to :employer
def questions
mini_post_questions
end
def surveys
mini_post_surveys
end
end
class MiniPostQuestion < ActiveRecord::Base
has_many :question_answers
belongs_to :mini_post
belongs_to :employer
def answers
question_answers
end
end
class MiniPostSurvey < ActiveRecord::Base
belongs_to :mini_post
belongs_to :employer
belongs_to :company
has_many :survey_invites
has_many :survey_responses, through: :survey_invites
def questions
mini_post.questions
end
end
class SurveyInvite < ActiveRecord::Base
belongs_to :mini_post_survey
has_many :survey_responses
def responses
survey_responses
end
end
class SurveyResponse < ActiveRecord::Base
belongs_to :survey_invite
has_many :question_answers
has_many :mini_post_questions, through: :question_answers
end
class QuestionAnswer < ActiveRecord::Base
belongs_to :survey_response
belongs_to :mini_post_question
validates :answer, presence: true
end
Here is my response form.
<div class="form-box">
<%= form_for #response, url: "/survey?key=#{#invite.key}", method: :post, html: { role: 'form' } do |f| %>
<% #questions.each do |question| %>
<div class="form-group">
<%= f.fields_for :mini_post_questions, question do |q| %>
<%= q.fields_for :question_answers, question.question_answers.build do |a| %>
<%= f.label question.question %>
<%= a.text_area :answer, class: 'form-control' %>
<%= a.hidden_field :survey_response_id, value: #survey.id %>
<% end %>
<% end %>
</div>
<% end %>
<div><%= f.submit "Submit", :class => "btn btn-primary" %></div>
<% end %>
</div>
My form renders correctly, however when I submit it, my params hash looks like this:
{"utf8"=>"✓",
"authenticity_token"=>"p8Tky2So10TH4FUUvLKhIh7j2vjNN39b3HDsF0cYE14=",
"survey_response"=>{"mini_post_questions"=>{"question_answers"=>{"answer"=>"", "survey_response_id"=>"11"}}},
"commit"=>"Submit",
"key"=>"e4fab42244db2286d471082696",
"controller"=>"surveys",
"action"=>"create"}
I would expect a mini_post_question key for each question, but I'm not sure how to get to that point.
I think you are on the right track, but you need to have your models accept nested attributes for the objects that you want in your form.
So I think in your SurveyResponse model, you would have
class SurveyResponse < ActiveRecord::Base
belongs_to :survey_invite
has_many :question_answers
accepts_nested_attributes_for :question_answers
has_many :mini_post_questions, through: :question_answers
end
Also, since it looks like you are not modifying the mini question here, I would say that you don't need to accept nested attributes for the questions, but just have a hidden field that assigns the mini_question_id to the question_answer
So your form should be something like this
<div class="form-box">
<%= form_for #response, url: "/survey?key=#{#invite.key}", method: :post, html: { role: 'form' } do |f| %>
<% #questions.each do |question| %>
<div class="form-group">
<%= f.fields_for :question_answers, #survey.question_answers.build do |q| %>
<%= q.label question.question %>
<%= q.text_area :answer, class: 'form-control' %>
<%= q.hidden_field :mini_post_question_id, value: question.id %>
<% end %>
</div>
<% end %>
<div><%= f.submit "Submit", :class => "btn btn-primary" %></div>
<% end %>
</div>
Since your form is accepting nested attributes for question_answers, you won't need to supply the survey_id.
This should get you closer to what you would need in your form.
I have a habtm model like:
class Recurrence < ActiveRecord::Base
has_many :participations, :include => :user
has_many :users, :through => :participations
accepts_nested_attributes_for :participations
attr_accessible :scheduled_to, :user_id, :user_ids
end
class Participation < ActiveRecord::Base
belongs_to :recurrence
belongs_to :user
attr_accessible :recurrence_id, :user_id
end
class User < ActiveRecord::Base
has_many :participations, :dependent => :delete_all
has_many :recurrences, :through => :participations
accepts_nested_attributes_for :participations
attr_accessible :name, :email, :phone, :recurrence_ids
end
with standard actions for the recurrences_controller (index, show, new, edit, create, update, destroy).
In the view of a single recurrence (/recurrences/10 -> show-action), I try to create/update the participation of user. When I do in the mentioned view something like:
<%= form_for #recurrence do |f| %>
<div class="checkbox">
<% for user in User.find(:all) %>
<div>
<%= check_box_tag "recurrence[user_ids][]", user.id, #recurrence.users.include?(user) %>
<%= user.name %>
</div>
<% end %>
</div>
<div class="actions">
<%= f.submit "Update", :class => 'btn btn-mini btn-primary' %>
</div>
<% end %>
erverything is working fine, I can add or remove the participation for one or more users.
BUT I like to do it - for just a single user, namely the current_user! I tried with the following source:
<%= form_for(#recurrence) do %>
<%= check_box_tag "recurrence[user_id]", current_user.id,
#recurrence.users.include?(current_user) %>
<%= current_user.name %>
<%= submit_tag "Update" %>
<% end %>
which is not working, more detailed
Updating the not changed status: not particpating, doesn't do anything: correct!
Changing status: from not participating - to participating, works for current_user, BUT will also delete the status of a other users: wrong!
Changing status: from participating - to not participating, won't change anything: wrong!
Any help is welcome!
Finaly I want to reduce the Check-Box to Confirm-/Refuse-Buttons with hidden-fields for the recurrence, but proabably there is easier rails-way?
I have recipe and ingredient in a many to many relation.
I have defined the following commands in my presentation.
<div>
<%= render :partial => 'ingredients/form',
:locals => {:form => recipe_form} %>
</div>
the partial begins with
<%= form_for(#ingredient) do |ingredient_form| %>
but received #ingredient nill.
Then I tried
<%= recipe_form.fields_for :ingredients do |builder| %>
<%= render 'ingredient_fields', f: builder %>
<% end %>
where my render was
<p class="fields">
<%= f.text_field :name %>
<%= f.hidden_field :_destroy %>
</p>
but nothing was printed.
then I tried
<% #recipe.ingredients.each do |ingredient| %>
<%= ingredient.name %>
<% end %>
and only then all of the ingredients were printed.
What was I doing wrong in the previous tries ?
Thank you.
my ingredient recipe relation defined as follows
class Ingredient < ActiveRecord::Base
has_many :ingredient_recipes
has_many :recipes, :through => :ingredient_recipes
...
class Recipe < ActiveRecord::Base
has_many :ingredient_recipes
has_many :ingredients, :through => :ingredient_recipes
...
accepts_nested_attributes_for :ingredient_recipes ,:reject_if => lambda { |a| a[:content].blank?}
class IngredientRecipe < ActiveRecord::Base
attr_accessible :created_at, :ingredient_id, :order, :recipe_id
belongs_to :recipe
belongs_to :ingredient
end
You don't exactly specify what you are trying to do, so I am presuming you have a page that shows a recipe, with many ingredients that can be edited and added to. In your controller you have something like:
class RecipeController < ApplicationController
def edit
#recipe = Recipe.find(params[:id]
end
end
I am also presuming that you are looking to have a form that post backs to the create action. I therefore think you want a form like this:
<%= form_for #recipe do |form| %>
<%= label_for :name %>
<%= text_field :name %>
<%= form.fields_for :ingredients do |ingredients_fields| %>
<div class="ingredient">
<%= f.text_field :name %>
<%= f.hidden_field :_destroy %>
</div>
<% end %>
<% end %>
Also, change your recipe to accept nested attributes for ingredients, not ingredient_recipes:
class Recipe < ActiveRecord::Base
has_many :ingredient_recipes
has_many :ingredients, :through => :ingredient_recipes
...
accepts_nested_attributes_for :ingredients, :reject_if => lambda { |a| a[:content].blank?}
And finally, add attr_accessible for your content:
class Ingredient < ActiveRecord::Base
attr_accessible :content
...
Does that work for you?
In this scenario I can insert values to the Member table and the Club table. But there is a field called :task in the memberships table that I want to submit a value to, and in the Memberships table member_id and club_id are inserted automatically by Rails. How do I include the task field in the form below? Thank you in advance.
View/form:
<%= form_for #member ,:url=>{:action =>"create"} do |f| %>
<%= f.text_field :email %>
<%= f.fields_for :clubs do |s| %>
<%= s.text_field :name %>
<% end %>
<%= f.submit "submit" %>
<% end %>
Models
class Member < ActiveRecord::Base
has_many :clubs ,:through=> :memberships
has_many :memberships
accepts_nested_attributes_for :clubs
attr_accessible :clubs_attributes
end
class Club < ActiveRecord::Base
has_many :members ,:through=>:memberships
has_many :memberships
end
class Memberships < ActiveRecord::Base
belongs_to :Member
belongs_to :Club
end
<%= f.fields_for :memberships do |m| %>
<%= m.text_field :task %>
<%= m.fields_for :clubs do |s| %>
<%= s.text_field :name %>
<% end %>
<% end %>