Basic Polymorphic Rails Form - ruby-on-rails

view (need help here) or do I need to change accepts_nested_attributes. I need a form that creates a property and associated address, beginning with City. At this point, I get the following error: unknown attribute: address. Further, I want to redirect back after create; not sure how to do that using inherited_resources. Thank you kindly.
= form_for Property.new do |f|
= f.fields_for :address do |builder|
= builder.label :city
= builder.text_field :city
= f.submit
class Property < ActiveRecord::Base
include ActiveRecord::Transitions
include ActsAsAsset
include Amendable
include Searchable
acts_as_taggable_on :tags
has_many :addresses, :as => :addressable
has_many :escrows
has_many :events, :as => :entity
has_many :phone_numbers, :as => :phoneable
accepts_nested_attributes_for :addresses
.
.
.
end
class Address < ActiveRecord::Base
belongs_to :addressable, :polymorphic => true
belongs_to :address_category
has_many :notes, :as => :notable
validate :not_blank
validates :addressable, :presence => true
private
def not_blank
self.errors.add :base, 'cannot be blank' if
self.attributes.values.all? {|attr| attr.blank? }
end
end
class PropertiesController < ApplicationController
inherit_resources
before_filter :authenticate_user!
def index
end
def show
end
end

Since it is a has_many relationship you need 'addresses' not 'address'.
Should be this:
= form_for Property.new do |f|
= f.fields_for :addresses do |builder|
= builder.label :city
= builder.text_field :city
= f.submit

Related

Rails: Use a collection of checkboxes to add/remove entries on a different table with ActiveRecord

I have three objects: Contact, Sector, and Contact_sector.
Contact contains an id and some other irrelevant (non-reference) columns
Sector contains an id and sector column with ~10 editable entries
Contact_sector has a contact_id reference and a sector_id reference. In my mind I imagine that every sector that applies to some contact can be found here, and if a sector is un-applied it is removed from here.
I want to have a collection of checkboxes in the contact _form formed from list of entries in :sectors, but updating the form with certain boxes ticked adds/removes entries from :contact_sectors.
Where am I going wrong?
UPDATED: Fixed strong_params to permit sectors, now I am unable to find the sectors by id ActiveRecord::RecordNotFound (Couldn't find Sector with ID=["1", ""] for Contact with ID=1)
Models:
class Contact < ActiveRecord::Base
has_many :contact_sectors
has_many :sectors, through: :contact_sectors
accepts_nested_attributes_for :contact_sectors, :reject_if => :all_blank, :allow_destroy => true
accepts_nested_attributes_for :sectors, :reject_if => :all_blank, :allow_destroy => true
end
class Sector < ActiveRecord::Base
has_many :contact_sectors
has_many :contacts, through: :contact_sectors
def name_with_initial
"#{sector}"
end
end
class ContactSector < ActiveRecord::Base
belongs_to :contact
belongs_to :sector
end
View:
<%= f.fields_for(:sectors) do |s| %>
<%= s.collection_check_boxes :id, Sector.all,
:id, :name_with_initial,
{ prompt: true }, { class: 'form-control' } %>
<% end %>
Controller
def edit
#contact.sectors.build
end
def contact_params
#Not sure if I need something like this or not
params['contact']['sectors'] = params['contact']['sectors']['id'].split(',')
params.require(:contact).permit(:firstname, :lastname,
contact_sectors_attributes: [:id],
sectors_attributes: [:_destroy, {:id => []}])
end
Instead of creating the join model explicitly you can just declare the relationship as has_many through: and let ActiveRecord handle the join model:
class Contact < ActiveRecord::Base
has_many :contact_sectors
has_many :sectors, through: :contact_sectors
accepts_nested_attributes_for :sector,
reject_if: :all_blank, allow_destroy: true
end
class Sector < ActiveRecord::Base
has_many :contact_sectors
has_many :contacts, through: :contact_sectors
end
class ContactSector < ActiveRecord::Base
belongs_to :contact
belongs_to :sector
end
<%= form_for(#contact) do |f| %>
<%= f.fields_for(:sectors) do |s| %>
<%= s.collection_check_boxes :id, Sector.all,
:id, :name_with_initial,
{ prompt: true }, { class: 'form-control' } %>
<% end %>
<% end %>
models
class Contact < ActiveRecord::Base
has_many :sectors, through: :contact_sectors
has_many :contact_sectors
accepts_nested_attributes_for :sectors
end
class Sector < ActiveRecord::Base
has_many :contacts, :through => :contact_sectors
has_many :contact_sectors
end
class ContactSector < ActiveRecord::Base
belongs_to :contact
belongs_to :sector
end
view
<%= form_for(#contact) do |f| %>
<% Sector.all.each do |sector| %>
<%= check_box_tag "contact[sector_ids][]", sector.id, f.object.sectors.include?(sector) %>
<%= sector.sector %>
<% end %>
<% end %>
controller
def update
#To make sure it updates when no boxes are ticked
#contact.attributes = {'sector_ids' => []}.merge(params[:contact] || {})
end
def contact_params
params.require(:contact).permit(:firstname, :lastname, sector_ids: [])
end
Recommended reading:
http://millarian.com/rails/quick-tip-has_many-through-checkboxes/
Rails 4 Form: has_many through: checkboxes

ActiveAdmin has_many relation record doesnt save

Im trying to save a post with category relation.
These are my models
class Post < ActiveRecord::Base
has_many :categorizes
has_many :post_categories, :through=>:categorizes
accepts_nested_attributes_for :post_categories
end
class PostCategory < ActiveRecord::Base
has_many :categorizes
has_many :posts, :through=>:categorizes
end
class Categorize < ActiveRecord::Base
belongs_to :post
belongs_to :post_category
end
and in ActiveAdmin post.rb.
ActiveAdmin.register Post do
permit_params :title, :content, post_category_ids:[:id]
index do
selectable_column
id_column
column :title
column :post_category_id
column :created_at
actions
end
filter :created_at
form do |f|
f.inputs "Post Details" do
f.input :title
f.input :content,:input_html => { :class => "tinymce_editor" }
#f.input :post_categories, :as=> :check_boxes#, :collection => PostCategory.all
end
f.has_many :post_categories ,new_record: false do |c|
c.inputs do
c.input :title
end
end
f.actions
end
controller do
defaults :finder => :find_by_slug_url
end
end
I need to see my all categories from post_categories and i should select more than one.
i check in rails console but the post hasnt any category.
Post.First.post_categories equal to []
Try post_category_attributes instead of post_category_ids
See more here.

Polymorphic Nested Form

I'm having issue creating a nested polymorphic form. I am following the solution from this problem:
Rails: has_many through with polymorphic association - will this work?
The description was: A Person can have many Events and each Event can have one polymorphic Eventable record
Here are the relevant models:
class Event < ActiveRecord::Base
belongs_to :person
belongs_to :eventable, :polymorphic => true
end
class Meal < ActiveRecord::Base
has_one :event, :as => eventable
end
class Workout < ActiveRecord::Base
has_one :event, :as => eventable
end
class Person < ActiveRecord::Base
has_many :events
has_many :meals, :through => :events, :source => :eventable,
:source_type => "Meal"
has_many :workouts, :through => :events, :source => :eventable,
:source_type => "Workout"
end
My controller looks like this:
def
#person = Person.new
#person.meals.new
#person.workouts.new
new
My view looks like this:
<%= form_for #person do |person| %>
<%= person.fields_for :meals, #person.meals.build do |meals| %>
<%= meals.text_field :food %>
<% end %>
<% end %>
The error I am currently getting is:
unknown attribute: person_id
I would think that the polymorphic association is hindering the creation of the object because meals can't be create until person has been created? Did I set up the form correctly? Thanks!
You'll need to include a person_id attribute in the events table (as per the belongs_to association)
There are also some other issues you should resolve:
Controller
def new
#person = Person.build
end
def create
#person = Person.new(person_attributes)
#person.save
end
private
def person_attributes
params.require(:person).permit(:your, :attributes, events_attributes: [:eventable_type, :eventable_id, meal_attributes: [:params], workout_attributes: [:params]])
end
Models
#app/models/person.rb
Class Person < ActiveRecord::Base
has_many :events
has_many :meals, :through => :events, :source => :eventable,
:source_type => "Meal"
has_many :workouts, :through => :events, :source => :eventable,
:source_type => "Workout"
def self.build
person = Person.new
person.events.build.build_meal
person.events.build.build_workout
end
end
Views
#app/views/people/new.html.erb
<%= form_for #person do |person| %>
<%= person.fields_for :events do |e| %>
<%= e.fields_for :meal %>
<%= e.text_field :food %>
<% end %>
<% end %>
<% end %>

accepts_nested_attributes_for with has_many polymorphic

I use paperclip to upload multi-file attached to studentcourseassignment,but i fail.
model
class StudentCourseAssignment < ActiveRecord::Base
attr_accessible :score, :comment, :finish_status,:attachments
accepts_nested_attributes_for :attachments
belongs_to :assignment
belongs_to :user
has_many :attachments ,:as => :attachmentable,:dependent => :destroy
end
class Attachment < ActiveRecord::Base
attr_accessible :user_upload
belongs_to :attachmentable , :polymorphic => true
has_attached_file :user_upload
end
controller
**new**
#sca = StudentCourseAssignment.new
#sca.attachments.build
#sca.attachments.build
**create**
#sca = StudentCourseAssignment.new(params[:student_course_assignment])
#assignment = Assignment.find(params[:assignment_id])
#sca.user = current_user
#sca.assignment = #assignment
if #sca.save
flash[:alert] = "success"
redirect_to course_years_path
else
flash[:alert] = "fail"
redirect_to course_years_path
end
** view**
<%= form_for #sca, :url => assignment_student_course_assignments_path(#assignment),
:html => { :id => 'student-assignment-form', :multipart => true } do |f| %>
file:
<%= f.fields_for :attachments do |a_f| %>
<%= a_f.file_field :user_upload %>
<%= submit_tag "create" %>
<% end%>
<% end %>
wrong
No association found for name `attachments'. Has it been defined yet?
if remove accepts_nested_attributes_for :attachments,it's still wrong
Attachment(#70201401779680) expected, got Array(#70201383294620)
hope your help!thx!
Change
from:
attr_accessible :score, :comment, :finish_status,:attachments
to:
attr_accessible :score, :comment, :finish_status,:attachments_attributes
I realize this is an old question, but fwiw I think you'll need to move
accepts_nested_attributes_for :attachments
to appear after
has_many :attachments, :as => :attachmentable,:dependent => :destroy
I hit this in a project once myself; pretty sure it boils down to accepts_nested_attributes_for expecting the relation to already be declared before its invoked.

fields_for with through relation

Item gets the collection_fields from his collections.
For each collection_field of the collection item may have a field_value
models
class Item < ActiveRecord::Base
belongs_to :collection
has_many :field_values, :dependent => :destroy
has_many :collection_fields, :through => :collection
accepts_nested_attributes_for :field_values, :allow_destroy => true
end
class Collection < ActiveRecord::Base
has_many :items, :dependent => :destroy
has_many :collection_fields, :dependent => :destroy
end
class CollectionField < ActiveRecord::Base
belongs_to :collection
belongs_to :field
has_many :items, :through => :collection
has_many :field_values, :dependent => :destroy
end
class Field < ActiveRecord::Base
has_many :collection_fields
end
class FieldValue < ActiveRecord::Base
belongs_to :item
belongs_to :collection_field
end
controller
def new
#item = Item.new
#item.collection = Collection.find(params[:collection])
#item.collection.collection_fields.each do |cf|
#item.collection_fields << cf
end
def edit
#item = Item.find(params[:id])
view
<%= form_for(#item, :html => { :multipart => true }) do |f| %>
<% #item.collection_fields.each do |cf| %>
<% f.label cf.field.name %>
<%= f.fields_for :field_values, cf.field_values.find_or_create_by_item_id(#item.id) do |fv| %>
<%= fv.text_field :valore %>
This code is working fine with the edit method, but when I try to add a new item I get:
Couldn't find FieldValue with ID=213 for Item with ID=
How should I implement these form fields correctly?
I've finally worked out a solution. It's not so elegant, but it works
- #collection.collection_fields.each do |cf|
= f.label cf.field.name
- if #item.new_record?
= f.fields_for :field_values, #item.field_values.build() do |field_value|
= field_value.text_field :valore
= field_value.hidden_field :collection_field_id, :value => cf.id
- else
= f.fields_for :field_values, #item.field_values.find_or_create_by_collection_field_id(cf.id) do |field_value|
%td= field_value.text_field :valore

Resources