lib/active_model/associations.rb
require 'active_model/associations/initialize_extension'
require 'active_model/associations/active_record_reflection'
require 'active_model/associations/autosave_association'
require 'active_model/associations/override_methods'
require 'active_record/associations/builder/has_many_for_active_model'
require 'active_record/associations/has_many_for_active_model_association'
require 'active_support/core_ext/module'
module ActiveModel
module Associations
extend ActiveSupport::Concern
include InitializeExtension
include AutosaveAssociation
include ActiveRecordReflection
include OverrideMethods
included do
mattr_accessor :belongs_to_required_by_default, instance_accessor: false
end
module ClassMethods
# define association like ActiveRecord
def belongs_to(name, scope = nil, options = {})
reflection = ActiveRecord::Associations::Builder::BelongsTo.build(self, name, scope, options)
ActiveRecord::Reflection.add_reflection self, name, reflection
end
# define association like ActiveRecord
def has_many(name, scope = nil, options = {}, &extension)
options.reverse_merge!(active_model: true, target_ids: "#{name.to_s.singularize}_ids")
if scope.is_a?(Hash)
options.merge!(scope)
scope = nil
end
reflection = ActiveRecord::Associations::Builder::HasManyForActiveModel.build(self, name, scope, options, &extension)
ActiveRecord::Reflection.add_reflection self, name, reflection
mixin = generated_association_methods
mixin.class_eval <<-CODE, __FILE__, __LINE__ + 1
def #{options[:target_ids]}=(other_ids)
@#{options[:target_ids]} = other_ids
association(:#{name}).reset
association(:#{name}).reset_scope
@#{options[:target_ids]}
end
CODE
end
end
end
end