首页 文章

覆盖ActiveRecord属性方法

提问于
浏览
145

我正在谈论的一个例子:

class Person < ActiveRecord::Base
  def name=(name)
    super(name.capitalize)
  end
  def name
    super().downcase  # not sure why you'd do this; this is just an example
  end
end

这似乎有效,但我刚刚阅读了ActiveRecord::Base docs中覆盖属性方法的部分,并建议使用 read_attributewrite_attribute 方法 . 我认为一定有什么不对的,因为我还要强迫一个更丑陋的习语,所以必须有充分的理由......

我真正的问题是:这个例子有问题吗?

4 回答

  • 89

    回应Gareth的评论......你的代码不会按照书面形式工作 . 它应该以这种方式重写:

    def name=(name)
      write_attribute(:name, name.capitalize)
    end
    
    def name
      read_attribute(:name).downcase  # No test for nil?
    end
    
  • 205

    作为Aaron Longwell答案的扩展,您还可以使用“哈希表示法”来访问具有被覆盖的访问器和更改器的属性:

    def name=(name)
      self[:name] = name.capitalize
    end
    
    def name
      self[:name].downcase
    end
    
  • -1

    有关该主题的一些很好的信息,请致电http://errtheblog.com/posts/18-accessor-missing .

    它的长短是ActiveRecord正确处理ActiveRecord属性访问器的超级调用 .

  • 7

    我有一个rails插件,可以让属性覆盖与super一起工作,就像你期望的那样 . 你可以在github找到它 .

    安装:

    ./script/plugin install git://github.com/chriseppstein/has_overrides.git
    

    使用:

    class Post < ActiveRecord::Base
    
      has_overrides
    
      module Overrides
        # put your getter and setter overrides in this module.
        def title=(t)
          super(t.titleize)
        end
      end
    end
    

    一旦你完成了这些事情就行了:

    $ ./script/console 
    Loading development environment (Rails 2.3.2)
    >> post = Post.new(:title => "a simple title")
    => #<Post id: nil, title: "A Simple Title", body: nil, created_at: nil, updated_at: nil>
    >> post.title = "another simple title"
    => "another simple title"
    >> post.title
    => "Another Simple Title"
    >> post.update_attributes(:title => "updated title")
    => true
    >> post.title
    => "Updated Title"
    >> post.update_attribute(:title, "singly updated title")
    => true
    >> post.title
    => "Singly Updated Title"
    

相关问题