【问题标题】:activerecord single table inheritance on ruby 3ruby 3上的activerecord单表继承
【发布时间】:2012-10-13 11:44:08
【问题描述】:

我有以下使用 STI 映射的类:

class Employee < ActiveRecord::Base
end

class StudentEmployee < Employee
  # I'd like to keep university only to StudentEmployee...
end
#Just to make this example easier to understand, not using migrations
ActiveRecord::Schema.define do
    create_table :employees do |table|
        table.column :name, :string
        table.column :salary, :integer
        table.column :university, :string # Only Students

    end
end

emp = Employee.create(:name=>"Joe",:salary=>20000,:university=>"UCLA")

我想禁止为员工设置大学字段,但允许为 StudentEmployees 设置。我尝试使用 attr_protected,但它只会阻止批量设置:

class Employee < ActiveRecord::Base
  attr_protected :university
end

class StudentEmployee < Employee
  attr_accessible :university
end
#This time, UCLA will not be assigned here
emp = Employee.create(:name=>"Joe",:salary=>20000,:university=>"UCLA")
emp.university = "UCLA" # but this will assign university to any student...
emp.save
puts "only Students should have univesities, but this guy has one..."+emp.university.to_s

这里的问题是它会在数据库中插入一所供简单员工使用的大学。 另一个问题是,我认为最好在 StudentEmployee 类中说大学是一个属性,而不是在 Employee 中说大学“不是”一个可见属性......它只是逆向自然抽象。

谢谢。

【问题讨论】:

  • 一种改进抽象的方法是用 attr_accessible 声明 Employee 和 StudentEmployee 的属性。但这不会阻止用户手动调用大学设置器。也许有一些私有方法的组合?或 ActiveRecord 处理缺失方法的方式进行了一些更改

标签: ruby activerecord orm ruby-on-rails-3.2 single-table-inheritance


【解决方案1】:

我会尝试这样的:

class Employee < ActiveRecord::Base
  validate :no_university, unless: lambda { |e| e.type === "StudentEmployee" }
  def no_university
    errors.add :university, "must be empty" unless university.nil?
  end
end

这不是最漂亮的,但它应该可以工作。

【讨论】:

  • 太棒了!只是一个简单的修复,它应该是“验证”,没有最后的“s”。而且我认为如果university.nil,它应该向'self.errors'添加一个错误msj?是假的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-01-13
  • 1970-01-01
  • 1970-01-01
  • 2013-06-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多