【问题标题】:Lowercase condition in "magic" methods for Model模型的“魔术”方法中的小写条件
【发布时间】:2012-02-19 02:18:36
【问题描述】:

模型Country 有一个属性code,它会通过before_save 回调自动转换为小写。是否可以在不重写大块 ActiveRecord::Base 的情况下将这种行为强制用于“魔术”方法?

class Country < ActiveRecord::Base
  attr_accessible :code
  validates :code, :presence => true
  validates_uniqueness_of :code, :case_sensitive => false

  before_save do |country|
    country.code.downcase! unless country.code.nil?
  end
end

RSpec

describe Country do
  describe 'data normalization'
    before :each do
      @country = FactoryGirl.create(:country, :code => 'DE')
    end

    # passes
    it 'should normalize the code to lowercase on insert' do
      @country.code.should eq 'de'
    end

    # fails
    it 'should be agnostic to uppercase finds' do
      country = Country.find_by_code('DE')
      country.should_not be_nil
    end 

    # fails
    it 'should be agnostic to uppercase finds_or_creates' do
      country = Country.find_or_create_by_code('DE')
      country.id.should_not be_nil # ActiveRecord Bug?
    end
end

【问题讨论】:

    标签: ruby-on-rails activerecord


    【解决方案1】:

    这就是我想出的,尽管我真的很讨厌这种方法(如问题中所述)。一个简单的替代方法是将列、表或整个数据库设置为忽略大小写(但这是 db 依赖)。

    class Country < ActiveRecord::Base
      attr_accessible :code
      validates :code, :presence => true
      validates_uniqueness_of :code, :case_sensitive => false
    
      before_save do |country|
        country.code.downcase! unless country.code.nil?
      end
    
      class ActiveRecord::Base
        def self.method_missing_with_code_finders(method_id, *arguments, &block)
          if match = (ActiveRecord::DynamicFinderMatch.match(method_id) || ActiveRecord::DynamicScopeMatch.match(method_id))
            attribute_names = match.attribute_names
            if code_index = attribute_names.find_index('code')
              arguments[code_index].downcase!
            end
          end
          method_missing_without_code_finders(method_id, *arguments, &block)
        end
    
        class << self
          alias_method_chain(:method_missing, :code_finders)
        end
      end
    end
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-08-08
      • 2021-06-26
      • 1970-01-01
      • 2018-01-23
      • 1970-01-01
      • 2015-09-13
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多