lib/classy-inheritance.rb in classy-inheritance-0.6.4 vs lib/classy-inheritance.rb in classy-inheritance-0.7.0
- old
+ new
@@ -1,15 +1,116 @@
+require 'active_record/version'
+module ActiveRecord
+ module Associations
+ class HasOneAssociation
+
+ # this is fixed in 2.3, but it doesn't hurt to leave it here
+ def set_belongs_to_association_for(record)
+ if @reflection.options[:as]
+ record["#{@reflection.options[:as]}_id"] = @owner.id unless @owner.new_record?
+ record["#{@reflection.options[:as]}_type"] = @owner.class.base_class.name.to_s
+ else
+ unless @owner.new_record?
+ primary_key = @reflection.options[:primary_key] || :id
+ record[@reflection.primary_key_name] = @owner.send(primary_key)
+ end
+ end
+ end
+
+ private
+ #this is still not fixed in 2.3
+ def new_record(replace_existing)
+ # Make sure we load the target first, if we plan on replacing the existing
+ # instance. Otherwise, if the target has not previously been loaded
+ # elsewhere, the instance we create will get orphaned.
+ load_target if replace_existing
+ record = @reflection.klass.send(:with_scope, :create => construct_scope[:create]) do
+ yield @reflection
+ end
+ if replace_existing
+ replace(record, true)
+ else
+ unless @owner.new_record?
+ primary_key = @reflection.options[:primary_key] || :id
+ record[@reflection.primary_key_name] = @owner.send(primary_key)
+ end
+ self.target = record
+ end
+
+ record
+ end
+ end
+ end
+
+ if ActiveRecord::VERSION::MAJOR == 2 && ActiveRecord::VERSION::MINOR == 3
+
+ module AutosaveAssociation
+
+ # fix active record has_one primary key bug rails 2.3 - http://rails.lighthouseapp.com/projects/8994/tickets/1756-has_one-with-foreign_key-primary_key-bug
+ def save_has_one_association(reflection)
+ if (association = association_instance_get(reflection.name)) && !association.target.nil?
+ primary_key = reflection.options[:primary_key] || :id
+ if reflection.options[:autosave] && association.marked_for_destruction?
+ association.destroy
+ elsif new_record? || association.new_record? || association[reflection.primary_key_name] != send(primary_key) || reflection.options[:autosave]
+ association[reflection.primary_key_name] = send(primary_key)
+ association.save(false)
+ end
+ end
+ end
+ end
+
+ end
+end
+
module Stonean
module ClassyInheritance
- VERSION = '0.6.4'
+ VERSION = '0.7.0'
def self.version
VERSION
end
-
+
module ClassMethods
+
+
+ # fix active record has_one primary key bug rails 2.2.2 - http://rails.lighthouseapp.com/projects/8994/tickets/1756-has_one-with-foreign_key-primary_key-bug
+ if ActiveRecord::VERSION::MAJOR == 2 && ActiveRecord::VERSION::MINOR == 2
+
+ def has_one(association_id, options = {})
+ if options[:through]
+ reflection = create_has_one_through_reflection(association_id, options)
+ association_accessor_methods(reflection, ActiveRecord::Associations::HasOneThroughAssociation)
+ else
+ reflection = create_has_one_reflection(association_id, options)
+
+ ivar = "@#{reflection.name}"
+
+ method_name = "has_one_after_save_for_#{reflection.name}".to_sym
+ define_method(method_name) do
+ association = instance_variable_get(ivar) if instance_variable_defined?(ivar)
+
+ primary_key = reflection.options[:primary_key] || :id
+ if !association.nil? && (new_record? || association.new_record? || association[reflection.primary_key_name] != send(primary_key))
+ association[reflection.primary_key_name] = send(primary_key)
+ association.save(true)
+ end
+ end
+ after_save method_name
+
+ add_single_associated_validation_callbacks(reflection.name) if options[:validate] == true
+ association_accessor_methods(reflection, ActiveRecord::Associations::HasOneAssociation)
+ association_constructor_method(:build, reflection, ActiveRecord::Associations::HasOneAssociation)
+ association_constructor_method(:create, reflection, ActiveRecord::Associations::HasOneAssociation)
+
+ configure_dependency_for_has_one(reflection)
+ end
+ end
+
+ end
+
def depends_on(model_sym, options = {})
define_relationship(model_sym,options)
# Optional presence of handling
if options.has_key?(:validates_presence_if) && options[:validates_presence_if] != true
@@ -39,11 +140,14 @@
end
options[:attrs].each{|attr| define_accessors(model_sym, attr, options)}
end
-
+ def has_dependency(model_sym, options = {})
+ depends_on(model_sym, options.update(:has_dependency => true))
+ end
+
def can_be(model_sym, options = {})
unless options[:as]
raise ArgumentError, ":as attribute required when calling can_be"
end
@@ -61,11 +165,11 @@
end
private
def classy_options
- [:as, :attrs, :prefix, :postfix, :validates_presence_if, :validates_associated_if]
+ [:as, :attrs, :has_dependency, :prefix, :postfix, :validates_presence_if, :validates_associated_if]
end
def delete_classy_options(options, *keepers)
options.delete_if do |key,value|
classy_options.include?(key) && !keepers.include?(key)
@@ -77,10 +181,12 @@
opts = delete_classy_options(options.dup, :as)
if opts[:as]
as_opt = opts.delete(:as)
opts = polymorphic_constraints(as_opt).merge(opts)
has_one model_sym, opts
+ elsif options[:has_dependency]
+ has_one model_sym, opts
else
belongs_to model_sym, opts
end
end
@@ -137,11 +243,11 @@
end
if options[:postfix]
accessor_method_name = (options[:postfix] == true) ? "#{accessor_method_name}_#{model_sym}" : "#{accessor_method_name}_#{options[:postfix]}"
end
-
+
define_method accessor_method_name do
eval("self.#{model_sym} ? self.#{model_sym}.#{attr} : nil")
end
define_method "#{accessor_method_name}=" do |val|
@@ -175,11 +281,11 @@
if Object.const_defined?("ActiveRecord") && ActiveRecord.const_defined?("Base")
module ActiveRecord::Validations::ClassMethods
def validates_associated_dependent(model_sym, options, configuration = {})
- configuration = { :message => I18n.translate('activerecord.errors.messages.invalid'), :on => :save }.update(configuration)
+ configuration = { :message => I18n.translate('activerecord.errors.messages')[:invalid], :on => :save }.update(configuration)
validates_each(model_sym, configuration) do |record, attr_name, value|
associate = record.send(attr_name)
if associate && !associate.valid?
associate.errors.each do |key, value|
@@ -193,11 +299,11 @@
end
end
end
end
end
-
-
+
ActiveRecord::Base.class_eval do
extend Stonean::ClassyInheritance::ClassMethods
end
+
end