UnknownAttributeError for nested form - ruby-on-rails-4

I have two model as:
Customer:
has_many :products, :dependent => :destroy
accepts_nested_attributes_for :products, reject_if: proc { |attributes| attributes['product_id'].blank? }
Product:
belongs_to :customer
products controller:
def product_params
params.require(:product).permit(:name, :first_build)
end
customers controller:
def customer_params
params.require(:customer).permit(:first_build, :name, :product_id,
products_attributes: [:first_build, :customer_id])
end
So in the customers controller I do this
#customer.products.build(:first_build => true)
but I get this error
unknown attribute 'first_build' for Prodcut
but when I do this #customer.products.build(:name => "test product name")
it works perfectly without any error. One thing to note here, first_build is not a column in the products table.

If you want to pass attributes that are not in the table, you can create a "temporary" attribute which will not be stored in the table but will be available while the object is in memory.
class Product < ActiveRecord::Base
attr_accessor :first_build
...
end

Related

Nested form has_many through issue

I have two models which are related with has_many :through association.
I have user & software_license models associated through user_software_license model. I am trying to save data using nested form, but I am getting errors
my models :
user.rb
has_many :software_licenses, through: :user_software_licenses
has_many :user_software_licenses
accepts_nested_attributes_for :software_licenses, :allow_destroy => true
software_license.rb
has_many :users, through: :user_software_licenses
has_many :user_software_licenses
accepts_nested_attributes_for :user_software_licenses
user_software_license.rb
belongs_to :user
belongs_to :software_license
my nested form :
= f.fields_for :software_licenses do |software_license|
= render :partial => "users/software_licenses", :locals => {:f => software_license}
= link_to_add_fields "Add", f, :user_software_licenses, true, "users/software_licenses"
this is how I am initialising it in my controller
user.software_licenses.build
and when I click on 'add more' button in nested form after submitting form I am getting parameters like this :
"software_licenses_attributes"=>{"0"=>{"id"=>"2"}},
"user_software_licenses"=>{"id"=>"2"},

Polymorphic Relationships in ActiveAdmin Forms in Rails 4

I have an Active Admin form where I need to be able to update/add a polymorphic relationship to an object. I can get the form to display it, but it won't update the table with the polymorphic relationship. The models are Category and TargetArea and they both have Tags. Here is the model setup:
#category.rb
class Category < ActiveRecord::Base
has_many :tags, as: :taggable
accepts_nested_attributes_for :tags
end
#tag.rb
class Tag < ActiveRecord::Base
belongs_to :category
belongs_to :target_area
belongs_to :taggable, polymorphic: true
accepts_nested_attributes_for :taggable
end
#Active Admin Form for Categories
permit_params :name, tags: []
form do |f|
f.actions
f.inputs 'Categories' do
f.input :name
f.inputs do
f.has_many :tags do |t|
t.input :name
end
end
end
f.actions
end
I want to be able to update and create new categories and add tags to the category in the form. I can't seem to find an example that does the same thing and this just doesn't seem to work.

Rails - use collection_select in a simple_form for a has_many_through association

I need help with a create form for a has_many_through association which also specifies a class name:
class Sponsor < ActiveRecord::Base
has_many :member_contacts
has_many :contacts, through: member_contacts, class_name: :member
accepts_nested_attributes_for :address, :contacts
end
class Contact < ActiveRecord::Base
has_many :member_contacts
has_many :sponsors, through: member_contacts
end
class MemberContact < ActiveRecord::Base
belongs_to :contact
belongs_to :sponsor
end
sponsors_controller.rb
def create
#sponsor = Sponsor.create(sponsor_params)
#sponsor.contacts.build
end
def sponsor_params
params.require(:sponsor).permit(:name,:website,:email,
:contact_first_name, :contact_surname, contacts_attributes: [], address_attributes: [:flat, :street, :postal_code, :city])
end
sponsor/_form.html.haml
= simple_form_for #sponsor do |f|
= f.association :contacts, collection: Member.all, label_method: :full_name
This is failing with the error 'unpermitted params, contact_ids', because
"contact_ids"=>["", "4", "5", "6"]
is being passed in the params hash. In the form I'd like a drop down list of all the members and the ability to select multiple members which will be saved against the sponsor as contacts.
How do I set up the contacts_attributes in sponsor_params in the controller and the collection_select simple_form helper in the view?
To get the form working, I added a foreign key to the sponsor class
has_many :contacts, through: member_contacts, class_name: 'Member', foreign_key 'member_id'
changed the strong params in the controller
def sponsor_params
params.require(:sponsor).permit(:name,:website,:email, contact_first_name, :contact_surname, contact_ids: [], address_attributes: [:flat, :street, :postal_code, :city])
end
and removed the association in the view, using collection_select
= f.collection_select :contact_ids, Member.all, :id, :full_name,
{ selected: #sponsor.contacts.map(&:id) }, { multiple: true }
You can set like this:
params.require(:sponsor).permit(:name,:website,:email, contact_ids: []...)
Note that permit(:contact_ids) will fail, but permit(contact_ids: []) works.

ActiveAdmin has_many through relationship not updating param Rails

I'm working through creating a has_many: through relationship in active admin. Here are the models as they stand:
class Category < ActiveRecord::Base
has_many :subcategories
end
class Subcategory < ActiveRecord::Base
has_many :product_in_subcategories
has_many :products, through: :product_in_subcategories
accepts_nested_attributes_for :product_in_subcategories, :allow_destroy => true
belongs_to :category
end
class Product < ActiveRecord::Base
has_many :product_in_subcategories
has_many :subcategories, through: :product_in_subcategories
accepts_nested_attributes_for :product_in_subcategories, :allow_destroy => true
end
class ProductInSubcategory < ActiveRecord::Base
belongs_to :product
belongs_to :subcategory
end
In ActiveAdmin I have the permit_params and form like so:
ActiveAdmin.register Product do
# note some params that are product only have been removed for simplicity
permit_params :name, subcategory_id:[:id], product_in_subcategories_attributes: [:id, :subcategory_id, :product_id, :_create, :_update]
form do |f|
f.inputs
f.has_many :product_in_subcategories do |s|
s.input :subcategory_id, :as => :check_boxes, :collection => Subcategory.all
end
f.actions
end
end
The form populates as should, and will save everything except for the subcategory_id. If I enter into the DB a proper subcategory_id the box will show checked on edit.
The messages when saving give:
Unpermitted parameters: subcategory_id
However, it appears it is trying to submit this with the product, for which there isn't a subcategory_id. Any ideas on what I am doing incorrectly here? This is driving me nuts and I've read everything I can find. I'd really like to understand what I'm doing wrong. Thanks.
After much time spent on this one, I couldn't find a suitable solution except for this one, which is actually very nice. It in fact is not much different from my envisioned solution:
The only changes to the above code were made in ActiveAdmin:
ActiveAdmin.register Product do
# note some params that are product only have been removed for simplicity
permit_params :name, product_in_subcategories_attributes: [:id, :subcategory_id, :product_id, :_create, :_update]
form do |f|
f.inputs
f.has_many :product_in_subcategories do |s|
s.input :subcategory_id, :as => :select, :collection => Subcategory.all
end
f.actions
end
end
Very strange how this allows a select box with no issues, but it flips out over check boxes. Nonetheless, I'm happy with the solution.

Rails has_many through association not updating join model

I have the following models:
class Project < ActiveRecord::Base
has_many :memberships
has_many :users, through: :memberships
end
class User < ActiveRecord::Base
has_many :memberships
has_many :projects, through: :memberships
end
class Membership < ActiveRecord::Base
belongs_to :user
belongs_to :project
end
and the migration for memberships
def change
create_table :memberships do |t|
t.belongs_to :user
t.belongs_to :project
t.boolean :admin
end
end
In my controller, I want to create a project for the current user
def create
#project = current_user.projects.build(project_params)
if #project.save
render json: #project, status: :ok
else
render json: { errors: #project.errors }, status: :unprocessable_entity
end
end
def project_params
params.require(:project).permit(:name)
end
When #project.save is called, the SQL in the log:
INSERT INTO "projects" ("created_at", "name", "updated_at") VALUES (?, ?, ?) [["created_at", "2014-12-09 17:18:55.298566"], ["name", "Test"], ["updated_at", "2014-12-09 17:18:55.298566"]]
So memberships is never updated, so the project gets made but it is not associated with the current user. I think rails is supposed to do that automatically when using the relationship to build the object, but that doesn't seem to be the case here.
It will work if I do
#project = current_user.projects.build(project_params)
#project.users << current_user
But that feels incorrect. Where am I going wrong?