在RoR中,无论何时创建嵌套资源,是否在模型中创建具有父关联的资源时设置属性?
我有这个角色模型,可能属于_to和其他角色。
employee = Role.find_by_slug :employee
employee.role
=> nil
employee.roles
=> [...more roles...]
waitress = employee.roles.create(slug: :waitress)
=> #<Role id...
waitress.role
=> #<Role slug: 'employee'...
waitress.roles
=> []
角色模型具有子类型的布尔属性。每当我从现有角色创建角色时,我都希望将子类型设置为true。
employee.subtype
=> false
女服务员看起来像这样:
waitress.subtype
=> true
答案 0 :(得分:1)
每当我从现有角色创建角色时,我都希望将子类型设置为true。
#app/models/Role.rb
class Role < ActiveRecord::Base
belongs_to :role
has_many :roles
validate :role_exists, if: "role_id.present?"
before_create :set_subtype, if: "role_id.present?"
private
def set_subtype
self.subtype = true
end
def role_exists
errors.add(:role_id, "Invalid") unless Role.exists? role_id
end
end
以上将需要另一个db请求;它只适用于创造和调用模型时会发生这种情况(IE可以在需要时随意调用它)。
-
另一种方法是使用acts_as_tree
或类似的层次结构宝石。
AAT在您的数据库中添加一个parent_id
列,然后它会附加一系列您可以调用的实例方法(parent
,child
等。)
这将允许您删除has_many :roles
,并将其替换为children
实例方法:
#app/models/role.rb
class Role < ActiveRecord::Base
acts_as_tree order: "slug"
#no need to have "subtype" column or has_many :roles etc
end
root = Role.create slug: "employee"
child1 = root.children.create slug: "waitress"
subchild1 = child1.children.create slug: "VIP_only"
root.parent # => nil
child1.parent # => root
root.children # => [child1]
root.children.first.children.first # => subchild1
答案 1 :(得分:0)
根据您的描述,如果给定的Role
没有父角色,则它被视为子类型。在这种情况下,只需将以下方法添加到Role
:
def subtype?
!self.role.nil?
end
答案 2 :(得分:0)
以下更改为我提供了诀窍:
从:
has_many :roles
到:
has_many :roles do
def create(*args, &block)
args[0][:subtype] = true
super(*args, &block)
end
end