module BazaModels::Model::HasOneRelations::ClassMethods

Public Instance Methods

has_one(relation_name, *all_args) click to toggle source

rubocop:disable Naming/PredicateName

# File lib/baza_models/model/has_one_relations.rb, line 8
def has_one(relation_name, *all_args)
  # rubocop:enable Naming/PredicateName

  args = all_args.pop

  relation = {
    type: :has_one,
    relation_name: relation_name,
    table_name: args[:table_name] || StringCases.pluralize(relation_name),
    args: args,
    all_args: all_args
  }

  if args[:foreign_key]
    relation[:foreign_key] = args.fetch(:foreign_key)
  else
    relation[:foreign_key] = :"#{StringCases.camel_to_snake(name)}_id"
  end

  relation[:dependent] = args.fetch(:dependent) if args[:dependent]

  if args && args[:class_name]
    relation[:class_name] = args.fetch(:class_name)
  else
    relation[:class_name] = StringCases.snake_to_camel(relation_name)
  end

  @has_one_relations ||= []
  @has_one_relations << relation

  relationships[relation_name] = relation

  define_method(relation_name) do
    if (model = autoloads[relation_name])
      model
    elsif relation[:args][:through]
      __send__(relation[:args][:through]).__send__(relation_name)
    else
      class_instance = StringCases.constantize(relation.fetch(:class_name))

      query = class_instance.where(relation.fetch(:foreign_key) => id)
      query.previous_model = self
      query.relation = relation

      all_args.each do |arg|
        query = query.instance_exec(&arg) if arg.is_a?(Proc)
      end

      query.first
    end
  end
end