Rails嵌套资源创建

时间:2016-01-02 21:39:03

标签: ruby-on-rails ruby activerecord

在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

3 个答案:

答案 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列,然后它会附加一系列您可以调用的实例方法(parentchild等。)

这将允许您删除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