I have two models.
fb_page.rb
has_one :fb_page_template, dependent: :destroy
accepts_nested_attributes_for :fb_page_template, :allow_destroy => false
fb_page_template.rb
belongs_to :fb_page
has_many :subscriptions
Active admin
ActiveAdmin.register FbPage do
form title: 'Facebook page form' do |f|
f.has_many :fb_page_template, new_record: false, allow_destroy: false do |k|
k.input :subscribed
end
end
end
Now when I try to update the form, it tries to delete subscriptions and fb_page_template as well.
All I want is to update the value of subscribed which is in fb_page_template
I think that you're missing couple things here:
You need to allow accepts_nested_attributes_for :subscriptions, :allow_destroy => false in your fb_page_template.rb
You need to allow all nested attributes in ActiveAdmin too.
You need to nest the forms.
This is what I have in my fb_pages.rb for ActiveAdmin:
ActiveAdmin.register FbPage do
permit_params :attribute_name_for_fb_page,
fb_page_template_attributes: [
:id, :fb_page_id, :attribute_name_for_fb_page_template,
subscriptions_attributes: [
:subscribed,
:fb_page_template_id
]
]
form title: "Facebook page form" do |f|
f.inputs do
f.input :attribute_name_for_fb_page
f.has_many :fb_page_template, allow_destroy: false do |t|
t.input :attribute_name_for_fb_page_template
t.has_many :subscriptions do |s|
s.input :subscribed, as: :boolean
end
end
end
f.actions
end
end
And this is what I have in the fb_page_template.rb
class FbPageTemplate < ApplicationRecord
belongs_to :fb_page
has_many :subscriptions
accepts_nested_attributes_for :subscriptions, :allow_destroy => false
end
Hope this works for you.
Related
I have associations as follows:
variant has_may colours and colours has_many sizes. I am using active admin gem for managing backend activities. My models looks like,
class Variant < ApplicationRecord
has_many :variant_colours, dependent: :destroy
accepts_nested_attributes_for : variant_colours, allow_destroy: true
end
class VariantColor < ApplicationRecord
belongs_to :variant
has_many :variant_sizes, dependent: :destroy
accepts_nested_attributes_for :variant_sizes, allow_destroy: true
end
class VariantSize < ApplicationRecord
belongs_to :variant_color
end
It is building variant_colours form with given fields but it is not building variant_sizes form under variant colours. Building meaning it does not populate fields on the form(UI)
form do |f|
f.inputs do
f.input :name
f.input :product
f.input :sku
f.input :stock_quantity
f.inputs do
f.has_many :variant_colors, heading: 'Variant Colors',
allow_destroy: true,
new_record: true do |color_form|
color_form.input :color
color_form.input :sku_code
color_form.input :stock
color_form.inputs do
color_form.has_many :variant_sizes, heading: 'Variant Sizes',
allow_destroy: true,
new_record: true do |size_form|
size_form.input :size
size_form.input :sku_code
size_form.input :stock
end
end
end
end
end
f.actions
end
May not need to wrap f.has_many with anything, so you could try removing one or both of the nested f.inputs and color_form.inputs that you have wrapping your has_many input blocks in the form.
My next thought would be, how are you declaring the permitted params in your controller? They probably need to be something along the lines of:
permit_params :name, :product, :sku, :stock_quantity,
variant_colors_attributes: [
:color, :sku_code, :stock, :_destroy,
# I don't think I've ever tried to double nest in this way, you may need diff syntax
variant_sizes_attributes: [:size, :sku_code, :stock, :_destroy]
]
My guess is the issue is in your permitted params.
Consider the following models:
class User < ApplicationRecord
accepts_nested_attributes_for :memberships, allow_destroy: true
has_many :memberships, dependent: :destroy
has_many :accounts, through: :memberships
end
class Account < ApplicationRecord
accepts_nested_attributes_for :memberships, allow_destroy: true
accepts_nested_attributes_for :users, allow_destroy: true
has_many :memberships, dependent: :destroy
has_many :users, through: :memberships
end
class Membership < ApplicationRecord
belongs_to :account
belongs_to :user
before_validation { self.role = "admin" if role.blank? }
validates :role, presence: true
pg_enum :role, %i[admin support user]
end
In ActiveAdmin there is already a form in place to create an Account and a Membership from an existing User. That looks like this:
form do |f|
...
f.inputs do
f.has_many :memberships, heading: false, allow_destroy: true, new_record: "Add existing user" do |m|
m.input :user_id, as: :searchable_select, ajax: { resource: User }
m.input :role, as: :select, label: false, include_blank: false
end
end
...
What I'm trying to do is update the form to allow a way to create an Account and a new User with a Membership with a specific role. This is what I've tried so far (within the same form block as the one above):
f.inputs do
f.has_many :users, heading: false, allow_destroy: true, new_record: "Add new user" do |u|
u.input :name
u.input :email, as: :string
u.has_many :memberships, heading: false, allow_destroy: true, new_record: "Add membership" do |m|
m.input :role, as: :select, label: false, include_blank: false
end
end
end
The form produced:
This doesn't work. If I don't fill in a role for the User's membership this will "work" and the before_validation in the Membership model will assign the User a Membership with role Admin. However, if I try to add a role to the User through the form and click "Create Account", then I am returned to the form where I see an error stating that Account must exist. This leads me to believe that the form is ignoring the second has_many that I've nested under f.has_many :users.
I've also tried approaching this by creating an input in the f.has_many :users block:
u.input :memberships, as: :select, label: "Role", include_blank: false, collection: Membership.roles
Instead of telling me that the Account must exist, this ignores any value I assign for the role, creates the User and assigns it a Membership with the role of Admin
How can I make this happen?
When you add through the form this is performed using JavaScript that includes before and after creation hooks I don't have an example but look at the code and see if it helps.
I have the following course.rb model
has_many :chapters
has_many :lectures, through: :chapters
has_many :enrols
has_many :contents, through: :lectures
has_many :users, -> { uniq }, through: :enrols
accepts_nested_attributes_for :chapters, allow_destroy: true
accepts_nested_attributes_for :lectures, allow_destroy: true
and course.rb active admin file
form title: 'Edit Course' do |f|
f.inputs 'Details' do
f.input :course_name
f.input :course_subtitle
f.input :course_description
f.input :video_link
f.input :course_language
f.input :status
f.input :course_image
end
# has_many :contents do |content|
# content.input :description
# content.input :attachment
# end
f.has_many :chapters, allow_destroy: true do |chapter|
# chapter.input :title
chapter.has_many :lectures do |lecture|
# lecture.input :title
# lecture.has_many :contents do |content|
# content.input :description
# end
lecture.input :title
end
end
actions
end
I am trying to make the content of course editable in the course form and it wud require multiple nested has_many since it has number of has_many through relation.
Right now I get undefined methodnew_record?' for nil:NilClass` error
How can it be done? Is there a better way to do it?
undefined method new_record?' for nil:NilClass`
Root cause:
chapter.has_many :lectures do |lecture|
Reason:
You have accepts_nested_attributes_for :lectures, allow_destroy: true in Course model, so you can't have a nested lecture inside Chapter
Solution:
chapter.has_many :lectures do |lecture|
should be
f.has_many :lectures do |lecture|
If you want to have nested lecture inside chapter, then remove accepts_nested_attributes_for :lectures, allow_destroy: true from Course model and add it inside Chapter model.
What if i want to add only the lecture? Your suggestion seem to work
but it gave me option to add lecutre and chapter
In that case, there is no need for f.has_many :chapters, allow_destroy: true do |chapter|. Just have f.has_many :lectures do |lecture|
i'm new to ActiveAdmin and Rails and i struggle on something to build up my ActiveAdmin interface.
Consider the following models :
class PageType < ActiveRecord::Base
has_many :fields, class_name: 'PageField'
accepts_nested_attributes_for :fields, allow_destroy: true
end
class PageField < ActiveRecord::Base
belongs_to :page_type
has_many :page_has_fields
has_many :pages, through: :page_has_fields
accepts_nested_attributes_for :page_has_fields, allow_destroy: true
end
class PageHasField < ActiveRecord::Base
belongs_to :page
belongs_to :page_field
end
class Page < ActiveRecord::Base
belongs_to :page_type
has_many :page_has_fields, dependent: :delete_all
has_many :page_fields, through: :page_has_fields
accepts_nested_attributes_for :page_fields, allow_destroy: true
end
In Active Admin I want to create some page templates to handle "static" pages. And in each of the pages, I want to update the content of each fields related to the templates page.
Thus far, what I did worked with this code :
ActiveAdmin.register Page do
permit_params :name, :page_type_id, :page_id,
:page_fields_attributes => [:id, :name, :field_type, :page_id,
:page_has_fields_attributes => [:id, :content, :page_id]
]
form do |f|
f.inputs
f.has_many :page_fields, heading: false, new_record: false do |g|
g.inputs :name, :required
g.has_many :page_has_fields, new_record: false do |h|
h.input :content if h.object.page_id == f.object.id
end
end
f.actions
end
end
But the second has_many seems really wrong to me, and i'm sure there are a better solution to this problem.
If i don't go with the "if", inputs are created for the right fields, but for every single page.
Is there a way to specify an ID or a parameter in has_many ? Or a better tag to handle situation like this ?
Thanks
Try changing your setup to something more like this
ActiveAdmin.register Page do
...
form do |f|
f.inputs do
f.input :some_column
f.input :some_other_column
f.input :page_fields, as: :check_boxes, checked: PageField.all.map(&:name)
f.input :page_has_fields, as: :check_boxes, checked: PageField.all.map(&:content)
end
f.actions
end
end
I'm fighting with this bug for the past few hours and I can't make sense of it and my researches didn't give an answer.
It is a basic HABTM relationship. Inputs HABTM Visualizations, and I have a cross table InputsVisualizations that has some attributes of its own.
= form_for(#visualization) do |f|
= f.input :title
= f.fields_for :inputs_visualizations do |iv|
= iv.input :color
= iv.fields_for :input do |i|
= i.input :title
= f.button :submit, "Save"
class Input < ActiveRecord::Base
# Associations ------------------
has_many :inputs_visualizations, dependent: :destroy, order: "inputs_visualizations.order ASC"
has_many :visualizations, through: :inputs_visualizations
# Attributes --------------------
attr_accessible :title, :unit
end
class InputsVisualization < ActiveRecord::Base
# Associations ------------------
belongs_to :input
belongs_to :visualization
# Attributes --------------------
attr_accessible :input_id, :visualization_id, :color, :input_attributes
accepts_nested_attributes_for :input, :reject_if => lambda { |i| i[:title].blank? }, :allow_destroy => true
end
class Visualization < ActiveRecord::Base
# Associations ------------------
has_many :inputs_visualizations, dependent: :destroy, order: "inputs_visualizations.order ASC"
has_many :inputs, through: :inputs_visualizations, order: "inputs_visualizations.order ASC"
# Attributes --------------------
attr_accessible :title, :inputs_visualizations_attributes
accepts_nested_attributes_for :inputs_visualizations, :reject_if => lambda { |a| a[:input_id].blank? }, :allow_destroy => true
end
I need a form for Visualizations that let me manage both InputsVisualizations and Inputs. As you can see in my form, there are two nested fields_for.
Case 1:
I create a nested InputsVisualization with a nested Input (both are new_record). I save the form, they both are created. Cool!
Case 2:
From the same form, I update an Input (existing record). I save, nothing is updated even though the attributes are properly passed to the controller.
I read that nested_attributes don't work with belongs_to relationship, though it created it just fine. Why doesn't it update afterwards?
Thanks
The :reject_if condition on this line looks for an :input_id but that value is not included in the form. So this could prevent the update from going through.
accepts_nested_attributes_for :inputs_visualizations, :reject_if => lambda { |a| a[:input_id].blank? }, :allow_destroy => true