How to customize fields_for - ruby-on-rails

I'm a rails newbie, today I got a problem with fields_for. Hope anyone can help me.
I have a model project:
class Project < ActiveRecord::Base
validates :project_name, presence: true,uniqueness: true
validates :plan_time, presence: true
has_many :tasks, dependent: :destroy
accepts_nested_attributes_for :tasks, allow_destroy: true
end
and a model task:
class Task < ActiveRecord::Base
belongs_to :user
belongs_to :project
validates :user_id, presence: true
validates :project_id, presence:true
end
but when I made a form_for project:
<%= form_for(#project, do |f| %>
<%= f.fields_for :tasks do |tasks_for_form|%>
<%= render 'task_fields', f: tasks_for_form%>
<%end%>
...
it render all the existing task of the project in db. plz help me!

That's what fields_for does, what are you expecting it to do?
If you want only fields for a new task, then you need to pass in a record object to the builder, for example:
<%= f.fields_for :tasks, #project.tasks.new do |tasks_for_form| %>
If you want add/remove functionality, you need to add that yourself, check out the cocoon gem which makes it simple to do so.

I'm not sure you've got end inside partial, but the end is required when fields_for has initiated.
<%= form_for(#project, do |f| %>
<%= f.fields_for :tasks do |tasks_for_form|%>
<%= render 'task_fields', f: tasks_for_form%>
<% end %>
<% end %>

Related

Validation failed: Park must exist, User must exist

I'm working on a project where Users can see dog Parks and make individual Playdates for each park. The issue I'm having is that the PlaydatesController create action is not persisting the user_id and park_id that each new playdate is associated with. I've tried adding optional: true to my Playdate model, which does save each playdate. However, doing this makes a null column entry for the user_id and park_id.
All I need is the user_id and park_id to create a playdate and keep the association between playdates and parks... Did I mess up my associations? Any help is GREATLY appreciated.
Here's my code:
Playdate MODEL:
class Playdate < ApplicationRecord
belongs_to :park
belongs_to :user
validates :date, presence: true
validates :time, presence: true
end
Park MODEL:
class Park < ApplicationRecord
has_many :playdates
has_many :comments
has_many :users, through: :comments
end
User MODEL:
class User < ApplicationRecord
has_many :parks
has_many :playdates
has_many :comments, through: :parks
end
Playdates CONTROLLER:
def create
#playdate = Playdate.new(playdate_params)
if #playdate.save!
redirect_to park_path(#park)
else
render :new
end
end
private
def playdate_params
params.require(:playdate).permit(:time, :date, :user_id, :park_id)
end
Playdates NEW VIEW:
<%= form_for #playdate do |f| %>
<%= f.label :date %>
<%= f.date_field :date %><br><br>
<%= f.label :time %>
<%= f.time_field :time %><br><br>
<%= hidden_field_tag :user_id, current_user.id %>
<%= hidden_field_tag :park_id, #park%>
<%= f.submit "Add Playdate!" %>
<% end %>
You should use:
f.hidden_field :user_id, value: current_user.id
f.hidden_field :park_id, value: #park.id
The rendered HTML is not the same between "hidden_field_tag" and "hidden_field". Try by yourself to see the difference.

Nested checkboxes in Rails

I'm trying to create an event app where each event has multiple tables and each table has multiple people sitting at a table the event has multiple tickets which map the people to the tables that they are sitting at -> in order to achieve this I have created a checkbox nested in the fields_for :tables (which is in turn in the event form) I presume something is wrong with either the strong parameters or the form itself but I have not been able to find any information that provides a solution to the problem.After checking the checkboxes in the form indicating which people are going to be sitting at this table and submitting the form and returning to the form I find that the checkboxes are no longer checked???
here are the contents of my model files
# models
class Event < ActiveRecord::Base
has_many :tables, dependent: :destroy
has_many :people , through: :tickets
has_many :tickets
accepts_nested_attributes_for :tickets, allow_destroy: true
accepts_nested_attributes_for :tables, allow_destroy: true
end
class Table < ActiveRecord::Base
belongs_to :event
has_many :tickets
has_many :people, through: :tickets
end
class Ticket < ActiveRecord::Base
belongs_to :table
belongs_to :person
end
class Person < ActiveRecord::Base
has_many :tickets
has_many :tables, through: :tickets
end
Here is the form with parts omitted for brevity.
<%= form_for(#event) do |f| %>
...
<%= f.fields_for :tables do |builder| %>
<%= render 'table_field', f: builder %>
<% end %>
<%= link_to_add_fields "Add Table", f, :tables %>
...
<% end %>
And here is the checkbox list I have implemented within the table_field.
<% Person.all.each do |person| %>
<div class="field">
<%= check_box_tag "table[people_ids][]", person.id, f.object.people.include?(person) %> <%= f.label [person.first_name, person.last_name].join(" ") %>
</div>
<% end %>
this is the event_params
def event_params
params.require(:event).permit(:name, :description, :start, :end, :latitude, :longitude, :address, :data, :people_ids => [], tables_attributes: [:id, :number, :size, :people_ids => []]).tap do |whitelisted|
whitelisted[:data] = params[:event][:data]
end
How do I get the checkboxes to be persistently checked in this form?
You can use http://apidock.com/rails/v4.0.2/ActionView/Helpers/FormOptionsHelper/collection_check_boxes
<%= f.collection_check_boxes(:people_ids, Person.all, :id, :name) do |person| %>
<%= person.label { person.check_box } %>
<% end %>
It will persist data as well.

Rails - How can I display one nested attributes

I have a new problem, I Create a web where I upload many images, using nested attributes and polymorphic table, in my index.html I want to show only one image, but I can't find how. But I'm new in rails.
photography.rb
class Photography < ActiveRecord::Base
validates :title, :description, presence: true
belongs_to :user
has_many :images, as: :imageable, dependent: :destroy
accepts_nested_attributes_for :images, :reject_if => lambda { |a| a[:img_str].blank? }, :allow_destroy => true
end
image.rb
class Image < ActiveRecord::Base
belongs_to :imageable, polymorphic: true
mount_uploader :img_str, AssetUploader
end
index.html.erb
<% for photo in #photo %>
<%= link_to photo.title, photography_path(photo) %>
<% photo.images.each do |images| %>
<%= images.img_str %>
<% end %>
<% end %>
With the for method I show all the image, try add .first, but says undefined method first for 5:Fixnum. I think that I have to create a helper method, but I not sure. Can anyone help me?. Thanks
Try:
<% for photo in #photo %>
<%= link_to photo.title, photography_path(photo) %>
<%= photo.images.first.img_str if photo.images.any? %>
<% end %>
Also, for is very rarely used in ruby, instead do:
<% #photos.each do |photo| %>

Plural for fields_for has_many association not showing in view

Currently, an Item belongs_to a Company and has_many ItemVariants.
I'm trying to use nested fields_for to add ItemVariant fields through the Item form, however using :item_variants does not display the form. It is only displayed when I use the singular.
I have check my associations and they seem to be correct, could it possibly have something to do with item being nested under Company, or am I missing something else?
Thanks in advance.
Note: Irrelevant code has been omitted from the snippets below.
EDIT: Don't know if this is relevant, but I'm using CanCan for Authentication.
routes.rb
resources :companies do
resources :items
end
item.rb
class Item < ActiveRecord::Base
attr_accessible :name, :sku, :item_type, :comments, :item_variants_attributes
# Associations
#-----------------------------------------------------------------------
belongs_to :company
belongs_to :item_type
has_many :item_variants
accepts_nested_attributes_for :item_variants, allow_destroy: true
end
item_variant.rb
class ItemVariant < ActiveRecord::Base
attr_accessible :item_id, :location_id
# Associations
#-----------------------------------------------------------------------
belongs_to :item
end
item/new.html.erb
<%= form_for [#company, #item] do |f| %>
...
...
<%= f.fields_for :item_variants do |builder| %>
<fieldset>
<%= builder.label :location_id %>
<%= builder.collection_select :location_id, #company.locations.order(:name), :id, :name, :include_blank => true %>
</fieldset>
<% end %>
...
...
<% end %>
You should prepopulate #item.item_variants with some data:
def new # in the ItemController
...
#item = Item.new
3.times { #item.item_variants.build }
...
end
Source: http://rubysource.com/complex-rails-forms-with-nested-attributes/
try this way
in your item controller new action write
def new
...
#item = # define item here
#item.item_variants.build if #item.item_variants.nil?
...
end
and in item/new.html.erb
<%= form_for #item do |f| %>
...
...
<%= f.fields_for :item_variants do |builder| %>
...
<% end %>
...
...
<% end %>
for more see video - Nested Model Form

Insert more than one item from a belongs_to association using nested forms

in my Rails way, I have just found another question to the commmunity.
I have the following project: I have a calendar which render me the events that any client have dealed with my company. If I want to insert a new event with only one client, I have no problem, but if I want to insert a new event with more than one client, I have a problem.
But it's been impossible to insert more than one client at the same time. I know that with this configuration, Rails only accepts one client for every instance of event, and one solution could be change the association model between Event and Client, but it makes no sense for me (event has_many clients and client belongs_to events... sounds weird). So, this post it's related to compile options from the community.
This is my code (I'm using the nested_form gem by Ryan Bates [github.com/ryanb/nested_form.git]):
UPDATE: By the moment, I introduce a new model Group, in this way:
models/group.rb
class Group < ActiveRecord::Base
has_many :clients
has_many :events
accepts_nested_attributes_for :clients
accepts_nested_attributes_for :events
attr_accessible :events_attributes, :clients_attributes
end
models/client.rb
class Client < ActiveRecord::Base
has_many :events
belongs_to :group
accepts_nested_attributes_for :events
accepts_nested_attributes_for :group, :update_only => true
attr_accessible :name, :surname, :email, :group_attributes, :events_attributes
end
models/event.rb
class Event < ActiveRecord::Base
belongs_to :group
accepts_nested_attributes_for :group, :update_only => true
attr_accessible :title, :group_id, :starts_at, :ends_at, :group_attributes
end
views/events/_form.html.erb
<%= simple_nested_form_for #event do |f| %>
<%= f.input :title %>
<%= f.fields_for :group do |group_form| %>
<%= group_form.fields_for :clients do |client_form| %>
<%= client_form.input :name %>
<%= client_form.input :surname %>
<%= client_form.input :email, :as => :email %>
<%= client_form.link_to_remove "Remove this client" %>
<% end %>
<%= group_form.link_to_add "Add another client", :clients %>
<% end %>
<%= f.input :starts_at, :as => :datetime %>
<%= f.input :ends_at, :as => :datetime %>
<%= f.button :submit %>
<% end %>
But know, my problem is that, when I create an event for one group, this group is successfully create when I insert ONLY ONE client. When I try to insert two or more clients I get the next:
ActiveModel::MassAssignmentSecurity::Error (Can't mass-assign protected attributes: new_1332430522879):
app/controllers/events_controller.rb:44:in `new'
app/controllers/events_controller.rb:44:in `create'
Ah! And I forget to comment before (but I think that is not relevant for that), that I'm using Ruby 1.9.3-p125 and Rails 3.2.2
Any ideas?
Thanks in advance...
Foncho

Resources