Class: Uchi::Field::HasMany

Inherits:
Field
  • Object
show all
Defined in:
app/components/uchi/field/has_many.rb

Defined Under Namespace

Classes: Edit, Index, Show

Constant Summary collapse

DEFAULT_COLLECTION_QUERY =
->(query:) { query }.freeze

Instance Method Summary collapse

Constructor Details

#initialize(name) ⇒ HasMany

Returns a new instance of HasMany.



136
137
138
139
140
# File 'app/components/uchi/field/has_many.rb', line 136

def initialize(name)
  super
  @collection_query = DEFAULT_COLLECTION_QUERY
  @nested_fields = []
end

Instance Method Details

#collection_query(query_proc = Configuration::Unset) ⇒ self, Proc

Sets or gets a custom query for filtering the collection of associated records.

When called with an argument, sets the query and returns self for chaining. When called without arguments, returns the current query.

Examples:

Setting

Field::HasMany.new(:users).collection_query(->(query:) {
  query.where(active: true)
})

Getting

field.collection_query # => #<Proc...>

Parameters:

  • query_proc (Proc, Symbol) (defaults to: Configuration::Unset) —

    A callable that receives an ActiveRecord query and returns a modified query.

Returns:

  • (self, Proc) —

    Returns self for method chaining when setting, or the query proc when getting



159
160
161
162
163
164
# File 'app/components/uchi/field/has_many.rb', line 159

def collection_query(query_proc = Configuration::Unset)
  return @collection_query if query_proc == Configuration::Unset

  @collection_query = query_proc
  self
end

#group_as(_action) ⇒ Object



166
167
168
# File 'app/components/uchi/field/has_many.rb', line 166

def group_as(_action)
  :associations
end

#nested_fields(*field_definitions) ⇒ self, Array

Sets or gets the fields to display inline for each associated record.

Configuring nested_fields switches this field from a select-and-link UI (for choosing existing records) to an inline editor that creates, edits, and deletes associated records directly within the parent form, using Rails' nested attributes pattern. The model must declare accepts_nested_attributes_for for this association.

When called with an argument, sets the fields and returns self for chaining. When called without arguments, returns the current fields.

Examples:

Setting with field instances

Field::HasMany.new(:titles).nested_fields(
  Field::String.new(:title),
  Field::String.new(:locale)
)

Setting with array

Field::HasMany.new(:titles).nested_fields([
  Field::String.new(:title),
  Field::String.new(:locale)
])

Getting

field.nested_fields # => [#<Uchi::Field::String>, #<Uchi::Field::String>]

Parameters:

  • field_definitions (Array<Uchi::Field>) —

    Field instances

Returns:

  • (self, Array) —

    Returns self for method chaining when setting, or the nested_fields array when getting



199
200
201
202
203
204
205
# File 'app/components/uchi/field/has_many.rb', line 199

def nested_fields(*field_definitions)
  return @nested_fields if field_definitions.empty?

  @nested_fields = field_definitions.flatten
  validate_nested_fields!
  self
end

#param_key ⇒ Object



207
208
209
210
211
212
213
# File 'app/components/uchi/field/has_many.rb', line 207

def param_key
  return :"#{name}_attributes" if nested_fields.any?

  # TODO: This is too naive. We need to match this to the actual foreign
  # key of the model.
  :"#{name.to_s.singularize}_ids"
end

#permitted_param ⇒ Object



215
216
217
218
219
# File 'app/components/uchi/field/has_many.rb', line 215

def permitted_param
  return {param_key => nested_permitted_params} if nested_fields.any?

  {param_key => []}
end