i have the following models:
class Order < ApplicationRecord
class Bill < Order
class Preorder < Order
class Detail < ApplicationRecord
class Metric < Detail
class Unit < Detail
the model Order
accept nested attributes for Detail
, an Order
can be a Bill
or a Preorder
and Detail
can be by Unit
or by Metric
i'm using jsonb_accessor gem to create additional attributes for Unit
and Metric
class Metric < Detail
jsonb_accessor :data,
height: :decimal,
width: :decimal
end
class Unit < Detail
jsonb_accessor :data,
quantity: :decimal
end
in my view, i'm using Cocoon gem to generate fields for Unit
or Metric
<%= link_to_add_association(I18n.t('activerecord.models.metric.add'), f, :details, data: {association_insertion_node: '#details', association_insertion_method: :append}, :class => "btn btn-success",
wrap_object: Proc.new { |detail| detail.type = "Metric"; detail = Metric.new }) %>
<%= link_to_add_association(I18n.t('activerecord.models.unit.add'), f, :details, data: {association_insertion_node: '#details', association_insertion_method: :append}, :class => "btn btn-success",
wrap_object: Proc.new { |detail| detail.type = "Unit"; detail = Unit.new }) %>
and in my controller, i have this method to verify the params
def order_params(type)
if type=="Bill"
params.require(:bill).permit(:client_id, :type, :delivered, :paid, :total_paid, details_attributes: [:id, :total_price, :type, :data, :service_id, :_destroy])
elsif type=="Preorder"
params.require(:preorder).permit(:client_id, :type, :delivered, details_attributes: [:id, :total_price, :type, :data, :service_id, :_destroy])
end
end
the form works near perfectly, it store all data i put in the form except for :width, :height, :quantity
, when i put them in params, it give an error saying that these params do not belong to Detail model and when i put :data
instead, the column still empty.
i'm considering, using column directly for parent model Detail
instead of using jsonb_accessor, or separate views and controller for each Metric
and Unit
models but i keep these solutions as last resort because i want to keep the code Dryier and use less columns as possible
Imho the problem is you are using the association details
which means that rails is trying to create/save a Detail
. Instead you will have to use the respective associations for units
and metrics
so rails knows to create the correct object which has the respective jsonb_accessors
to save correctly.
You can just add the associations in the model:
has_many :metrics
has_many :units
I get this is possibly not as clean in your UI (if everything is a detail you can just add/list them together). Another alternative is define all possible json-fields in your Detail
model (but not entirely sure if that defeats the purpose of using them in the first place).