在Rails3中提交之前防止/验证子关系的创建

时间:2013-03-25 09:46:40

标签: ruby-on-rails ruby-on-rails-3 cancan

我正在尝试阻止我的用户在与不属于他们的记录的'has many through'关联中创建关系。

我的用户通过location_users拥有多个位置。他们的位置通过location_shops有许多商店。我目前用CanCan保护了一些东西。

class User < ActiveRecord::Base
  has_many :locationusers
  has_many :locations, :through => :locationusers  
end

class Location < ActiveRecord::Base
  has_many :locationusers
  has_many :users, :through => :locationusers
  has_many :location_shops
  has_many :shops, :through => :location_shops
end

class Shop < ActiveRecord::Base
  has_many :location_shops
  has_many :locations, :through => :location_shops
end

我的康康技能

class Ability
  can [:manage], Shop, { :locationusers => {:user_id => user.id }}
  can [:manage], Location, { :locationusers => {:user_id => user.id }}
end

我可以通过此设置处理位置的创建/编辑,我的用户只能查看/编辑他们自己的位置/商店。

问题在于创建这些关系。

如果用户发布了不属于他们的位置ID,则无论他们是否具有创建关系的权限,都会创建该关系。当然,他们无法查看这种关系,但我需要首先阻止创建。

例如,具有ID为314的单个位置的用户

>> User.last.locations.map(&:id)
=> [314]

在创建新店铺时,如果我更改了张贴的栏目:

:shop=>{:shop_name=>"Ye Old Shoppe", :location_ids => [1,2,3,314]}}

上面显然创建了四个位置的关系。我需要它来在创建关系之前验证位置ID。

我唯一想到的就是在模型中添加before_add:

class Location
  has_many :location_shops
  has_many :shops, :through => :location_shops, :before_add => :check_location_ownership
end

这是正确的方法,如果是这样,应该是什么:check_location_ownership看起来像什么?或者,有没有更好的方法来阻止关系的创建?

1 个答案:

答案 0 :(得分:1)

虽然你所做的事情确实有意义,但我还有其他两种方法可以考虑。

1)在:conditions关系中使用has_many选项。

2)自定义验证方法。

class Location
  has_many :location_shops
  has_many :shops, :through => :location_shops
  validate :check_location_ownership
end

我会亲自根据具体情况选择其中一种。