Project

General

Profile

Download (2.76 KB) Statistics
| Branch: | Tag: | Revision:
3b656b8d Joseph Mitchell Magen
module HasManyCommon
extend ActiveSupport::Concern

def assoc_klass(association)
1cf860b7 Stephen Benjamin
self.class.reflect_on_association(association).klass
3b656b8d Joseph Mitchell Magen
end

832c0925 Joseph Magen
# calls method :name or whatever is defined in attr_name :title
3b656b8d Joseph Mitchell Magen
def name_method
send(self.class.attribute_name)
end

module ClassMethods
# default attribute used by *_names and *_name is :name
# if :name doesn't exist, :id is used, so it doesn't error out if attr_name :field is not defined
# most likely model will have attr_name :field to overwrite attribute_name
def attribute_name
if has_name?
:name
else
:id
end
end

4f7a4d0b David Davis
def has_name?(field = "name")
3b656b8d Joseph Mitchell Magen
self.column_names.include?(field)
end

# class method in model to overwrite default attribute_name
# Ex.
# Class Hostgroup
832c0925 Joseph Magen
# attr_name :title
3b656b8d Joseph Mitchell Magen
def attr_name(attribute)
self_class.send(:define_method, "attribute_name") do
attribute
end
end

def self_class
class << self; self end
end

#### has_many ####
fb9f45e8 Daniel Lobato
def has_many(*args)
options = args.last.is_a?(Hash) ? args.last : {}
has_many_names_for(args.first, options)
3b656b8d Joseph Mitchell Magen
super
end

def has_and_belongs_to_many(association, options = {})
has_many_names_for(association, options)
super
end

def has_many_names_for(association, options)
assoc = association.to_s.tableize.singularize

# SETTER _names= method
define_method "#{assoc}_names=" do |name_values|
ids = Array.wrap(name_values).map do |name_value|
assoc_klass(association).send("find_by_#{assoc_klass(association).attribute_name}", name_value).id
end
self.send("#{assoc}_ids=", ids)
end

# GETTER _names method
define_method "#{assoc}_names" do
9e892b43 Tomer Brisker
self.send(association).map(&:name_method)
3b656b8d Joseph Mitchell Magen
end
end

#### belongs_to ####
fb9f45e8 Daniel Lobato
def belongs_to(*args)
options = args.last.is_a?(Hash) ? args.last : {}
belongs_to_name_for(args.first, options)
3b656b8d Joseph Mitchell Magen
super
end

def belongs_to_name_for(association, options)
assoc = association.to_s.tableize.singularize
7c671609 Dominic Cleal
assoc_name = options.delete(:name_accessor) || "#{assoc}_name"
3b656b8d Joseph Mitchell Magen
# SETTER _name= method
7c671609 Dominic Cleal
define_method "#{assoc_name}=" do |name_value|
65af0932 Shlomi Zadok
assoc_id = assoc_klass(association).send("find_by_#{assoc_klass(association).attribute_name}", name_value).try(:id)
d7c67746 Michael Moll
unless assoc_id
raise Foreman::AssociationNotFound
.new(_("Could not find %{association} with name: %{name}") % { name: name_value, association: association })
end
3b656b8d Joseph Mitchell Magen
self.send("#{assoc}_id=", assoc_id)
end

# GETTER _name method
7c671609 Dominic Cleal
define_method assoc_name do
9e892b43 Tomer Brisker
self.send(association).try(:name_method)
3b656b8d Joseph Mitchell Magen
end
end
end
end