2013-03-25 46 views
0

我试图阻止我的用户在“有很多通过”关联中创建一个不属于他们的记录的关系。在Rails3中提交之前防止/验证子关系的创建

我的用户通过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] 

当创建一个新的店,如果我改变PARAMS贴:

: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

虽然你所做的事情确实有道理,但我还能想到其他两种方法。

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

2)自定义验证方法。

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

我个人会根据情况选择其中之一。

+0

感谢您的回答。 check_location_ownership必须做什么?循环访问location_ids并确保它们都属于客户? – simonmorley 2013-03-25 10:44:04

+0

是的。你应该可以通过self.shops.each(&:location_id)访问它们(因为有很多!) – Chirantan 2013-03-25 13:18:03

+0

非常感谢您的帮助。很高兴得到一个令人放心的答案:) S – simonmorley 2013-03-25 16:59:51