Class: HasHelpers::BaseConstructor
- Inherits:
-
SimpleDelegator
- Object
- SimpleDelegator
- HasHelpers::BaseConstructor
- Defined in:
- app/constructors/has_helpers/base_constructor.rb
Class Attribute Summary collapse
-
.has_many_ids_associations ⇒ Object
readonly
Returns the value of attribute has_many_ids_associations.
Class Method Summary collapse
-
.has_many_ids(*associations) ⇒ Object
Sets up the constructor to handle
[association_ids]attributes, without immediately executing the database statements, which is the Rails default.
Instance Method Summary collapse
Class Attribute Details
.has_many_ids_associations ⇒ Object (readonly)
Returns the value of attribute has_many_ids_associations.
9 10 11 |
# File 'app/constructors/has_helpers/base_constructor.rb', line 9 def has_many_ids_associations @has_many_ids_associations end |
Class Method Details
.has_many_ids(*associations) ⇒ Object
Sets up the constructor to handle [association_ids] attributes, without
immediately executing the database statements, which is the Rails default.
Example
Class Report::Constructor < :HasHelpersBaseConstructor
class Report has an association: has_many :users, through: :shares
has_many_ids :users end
The example above will allow report[user_ids] attribute to be set
and build the associated objects in memory. In this case, if
report[user_ids] = [1], it will execute report.shares.build(user_id: 1)
Any existing objects with the ids not included in this parameter will
be marked for destruction.
25 26 27 28 |
# File 'app/constructors/has_helpers/base_constructor.rb', line 25 def has_many_ids(*associations) @has_many_ids_associations ||= [] @has_many_ids_associations.concat associations end |
Instance Method Details
#assign_attributes(object_attrs) ⇒ Object
31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 |
# File 'app/constructors/has_helpers/base_constructor.rb', line 31 def assign_attributes(object_attrs) attrs = object_attrs.dup # Build/destroy has_many objects from "object_ids" params self.class.has_many_ids_associations.each do |association_name| association = object.class.reflect_on_association(association_name) association_key = association.foreign_key.to_s.pluralize association_to_build = association.through_reflection if attrs[association_key] association_primary_key = association.association_primary_key.to_s type_caster = association.klass.type_caster # Get ids from parameters, casting them to their correct type for the database. object_ids = attrs.delete(association_key).select(&:present?).map { |val| type_caster.type_cast_for_database(association_primary_key, val) } persisted_object_ids = object.send(association.name).map(&:id) # Mark for destruction any object that's not included in the attributes. object.send(association_to_build.name).reject do |assc_object| # skip any object that doesn't have this foreign key set. assc_object.send(association.foreign_key).blank? || object_ids.include?(assc_object.send(association.foreign_key)) end.each(&:mark_for_destruction) (object_ids - persisted_object_ids).each do |new_object_id| object.send(association_to_build.name).build(association.foreign_key => new_object_id) end end end object.assign_attributes(attrs) end |