Module: Torque::PostgreSQL::Base::ClassMethods
- Defined in:
- lib/torque/postgresql/base.rb
Instance Method Summary collapse
-
#belongs_to_many(name, scope = nil, **options, &extension) ⇒ Object
Specifies a one-to-many association.
-
#inherited(subclass) ⇒ Object
Wenever it's inherited, add a new list of auxiliary statements It also adds an auxiliary statement to load inherited records' relname.
-
#upsert_all(attributes, **xargs) ⇒ Object
Allow extra keyword arguments to be sent to
InsertAll.
Instance Method Details
#belongs_to_many(name, scope = nil, **options, &extension) ⇒ Object
Specifies a one-to-many association. The following methods for retrieval and query of collections of associated objects will be added:
collection is a placeholder for the symbol passed as the name
argument, so belongs_to_many :tags would add among others
tags.empty?.
[collection]
Returns a Relation of all the associated objects.
An empty Relation is returned if none are found.
[collection<<(object, ...)]
Adds one or more objects to the collection by adding their ids to
the array of ids on the parent object.
Note that this operation instantly fires update SQL without waiting
for the save or update call on the parent object, unless the parent
object is a new record.
This will also run validations and callbacks of associated
object(s).
[collection.delete(object, ...)]
Removes one or more objects from the collection by removing their
ids from the list on the parent object.
Objects will be in addition destroyed if they're associated with
dependent: :destroy, and deleted if they're associated
with dependent: :delete_all.
[collection.destroy(object, ...)]
Removes one or more objects from the collection by running
destroy on each record, regardless of any dependent option,
ensuring callbacks are run. They will also be removed from the list
on the parent object.
[collection=objects]
Replaces the collections content by deleting and adding objects as
appropriate.
[collection_singular_ids]
Returns an array of the associated objects' ids
[collection_singular_ids=ids]
Replace the collection with the objects identified by the primary
keys in ids. This method loads the models and calls
collection=. See above.
[collection.clear]
Removes every object from the collection. This destroys the
associated objects if they are associated with
dependent: :destroy, deletes them directly from the
database if dependent: :delete_all, otherwise just remove
them from the list on the parent object.
[collection.empty?]
Returns true if there are no associated objects.
[collection.size]
Returns the number of associated objects.
[collection.find(...)]
Finds an associated object according to the same rules as
ActiveRecord::FinderMethods#find.
[collection.exists?(...)]
Checks whether an associated object with the given conditions exists.
Uses the same rules as ActiveRecord::FinderMethods#exists?.
[collection.build(attributes = {}, ...)]
Returns one or more new objects of the collection type that have
been instantiated with attributes and linked to this object by
adding its id to the list after saving.
[collection.create(attributes = {})]
Returns a new object of the collection type that has been
instantiated with attributes, linked to this object by adding its
id to the list after performing the save (if it passed the
validation).
[collection.create!(attributes = {})]
Does the same as collection.create, but raises
ActiveRecord::RecordInvalid if the record is invalid.
[collection.reload]
Returns a Relation of all of the associated objects, forcing a
database read. An empty Relation is returned if none are found.
Example
A Video class declares belongs_to_many :tags, which will add:
- Video#tags (similar to Tag.where([id] && tag_ids))
- Video#tags<<
- Video#tags.delete
- Video#tags.destroy
- Video#tags=
- Video#tag_ids
- Video#tag_ids=
- Video#tags.clear
- Video#tags.empty?
- Video#tags.size
- Video#tags.find
- Video#tags.exists?(name: 'ACME')
- Video#tags.build
- Video#tags.create
- Video#tags.create!
- Video#tags.reload
The declaration can also include an
optionshash to specialize the behavior of the association.
Options
[:class_name]
Specify the class name of the association. Use it only if that name
can't be inferred from the association name. So belongs_to_many
:tags will by default be linked to the Tag class, but if the
real class name is SpecialTag, you'll have to specify it with this
option.
[:foreign_key]
Specify the foreign key used for the association. By default this is
guessed to be the name of this class in lower-case and "_ids"
suffixed. So a Video class that makes a #belongs_to_many association
with Tag will use "tag_ids" as the default :foreign_key.
It is a good idea to set the <tt>:inverse_of</tt> option as well.
[:primary_key]
Specify the name of the column to use as the primary key for the
association. By default this is id.
[:dependent]
Controls what happens to the associated objects when their owner is
destroyed. Note that these are implemented as callbacks, and Rails
executes callbacks in order. Therefore, other similar callbacks may
affect the :dependent behavior, and the :dependent
behavior may affect other callbacks.
[:touch]
If true, the associated objects will be touched (the updated_at/on
attributes set to current time) when this record is either saved or
destroyed. If you specify a symbol, that attribute will be updated
with the current time in addition to the updated_at/on attribute.
Please note that with touching no validation is performed and only
the after_touch, after_commit and after_rollback callbacks are
executed.
[:optional]
When set to true, the association will not have its presence
validated.
[:required]
When set to true, the association will also have its presence
validated. This will validate the association itself, not the id.
You can use :inverse_of to avoid an extra query during validation.
NOTE: required is set to false by default and is
deprecated. If you want to have association presence validated,
use required: true.
[:default]
Provide a callable (i.e. proc or lambda) to specify that the
association should be initialized with a particular record before
validation.
[:inverse_of]
Specifies the name of the #has_many association on the associated
object that is the inverse of this #belongs_to_many association.
See ActiveRecord::Associations::ClassMethods's overview on
Bi-directional associations for more detail.
Option examples:
belongs_to_many :tags, dependent: :nullify
belongs_to_many :tags, required: true, touch: true
belongs_to_many :tags, default: -> { Tag.default }
203 204 205 206 207 |
# File 'lib/torque/postgresql/base.rb', line 203 def belongs_to_many(name, scope = nil, **, &extension) klass = Associations::Builder::BelongsToMany reflection = klass.build(self, name, scope, , &extension) ::ActiveRecord::Reflection.add_reflection(self, name, reflection) end |
#inherited(subclass) ⇒ Object
Wenever it's inherited, add a new list of auxiliary statements It also adds an auxiliary statement to load inherited records' relname
17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 |
# File 'lib/torque/postgresql/base.rb', line 17 def inherited(subclass) super subclass.class_attribute(:auxiliary_statements_list) subclass.auxiliary_statements_list = {} record_class = ActiveRecord::Relation._record_class_attribute # Define helper methods to return the class of the given records subclass.auxiliary_statement record_class do |cte| pg_class = ::Arel::Table.new('pg_class') arel_query = ::Arel::SelectManager.new(pg_class) arel_query.project(pg_class['oid'], pg_class['relname'].as(record_class.to_s)) cte.query 'pg_class', arel_query.to_sql cte.attributes col(record_class) => record_class cte.join tableoid: :oid end # Define the dynamic attribute that returns the same information as # the one provided by the auxiliary statement subclass.dynamic_attribute(record_class) do next self.class.table_name unless self.class.physically_inheritances? pg_class = ::Arel::Table.new('pg_class') source = ::Arel::Table.new(subclass.table_name, as: 'source') quoted_id = ::Arel::Nodes::Quoted.new(id) query = ::Arel::SelectManager.new(pg_class) query.join(source).on(pg_class['oid'].eq(source['tableoid'])) query.where(source[subclass.primary_key].eq(quoted_id)) query.project(pg_class['relname']) self.class.connection.select_value(query) end end |
#upsert_all(attributes, **xargs) ⇒ Object
Allow extra keyword arguments to be sent to InsertAll
210 211 212 213 |
# File 'lib/torque/postgresql/base.rb', line 210 def upsert_all(attributes, **xargs) xargs = xargs.merge(on_duplicate: :update) ::ActiveRecord::InsertAll.new(self, attributes, **xargs).execute end |