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