有没有办法让Rails ActiveRecord属性私有?

时间:2010-09-21 22:13:54

标签: ruby-on-rails activerecord private

默认情况下,ActiveRecord从相应的数据库表中获取所有字段,并为所有字段创建公共属性。

我认为将模型中的所有属性公开是合理的。更重要的是,暴露出供内部使用的属性会使模型的界面混乱,并违反封装原则。

那么,有没有办法按字面意思private制作一些属性?

或者,也许我应该转向其他ORM?

7 个答案:

答案 0 :(得分:32)

Jordini大部分都在那里

大多数active_record都发生在method_missing中。如果你预先定义方法,它将不会触及该方法的method_missing,而是使用你的方法(有效覆盖,但不是真的)

class YourModel < ActiveRecord::Base

  private

  def my_private_attribute
    self[:my_private_attribute]
  end

  def my_private_attribute=(val)
    write_attribute :my_private_attribute, val
  end

end

答案 1 :(得分:5)

好吧,你总是可以覆盖方法......

class YourModel < ActiveRecord::Base

  private

  def my_private_attribute
    self[:my_private_attribute]
  end

  def my_private_attribute=(val)
    self[:my_private_attribute] = val
  end

end

答案 2 :(得分:5)

最近偶然发现了这一点。如果你想私人写作和阅读以及公开阅读这样的话

class YourModel < ActiveRecord::Base

  attr_reader :attribute

  private

  attr_accessor :attribute


end

对我来说似乎很好。您可以使用attr_reader,attr_writer和attr_accessor来决定应该公开什么以及应该私有什么。

答案 3 :(得分:1)

您可以将现有方法设为私有:

YourClass.send(:private, :your_method)

答案 4 :(得分:1)

对我来说,来自Otto和jordinl的方法都运行正常,并使得对象Class的rspec传递:

object.should_not respond_to :attribute

但是当我使用jordinl方法时,我有一个弃用消息,不能直接写入数据库,而是使用attr_writer。

更新:

但真正做到这一点的“正确”方法结果却很简单。感谢MladenJablanović和Christopher Creutzig from here。要使预定义方法成为私有或受保护的...只需重新定义它:

Class Class_name

  private :method_name
  protected :method_name_1
end

重要的是,您无需重写以前定义的方法的逻辑。

答案 5 :(得分:0)

将设置设为私有会产生ActiveRecord错误。

我通过检查调用者将访问控制代码放在公共setter的覆盖方法中:

def my_private_attribute=(val)
  if (caller.first.include?('active_record/base.rb') || caller.first.include?('app/models/myclass.rb'))
    self[:my_private_attribute] = val
  else
     raise Exception.new("Cannot set read-only attribute.")
  end
end

答案 6 :(得分:0)

我认为有100%可靠的方法可以做到这一点。它还值得检查最常用的访问属性的方法:

http://www.davidverhasselt.com/set-attributes-in-activerecord/