0

私は、ユーザーが自分に属していないレコードとの関連付けで「多くのスルー」の関係を作成できないようにしようとしています。

私のユーザーは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を投稿すると、関係を作成する権限があるかどうかに関係なく、関係が作成されます。確かに、彼らはこの関係を見ることができませんが、私はそもそも作成を防ぐ必要があります。

たとえば、ID314の単一の場所を持つユーザー

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

新しいショップを作成するときに、投稿されたパラメータを変更すると、次のようになります。

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

上記は明らかに4つの場所の関係を作成します。リレーションシップを作成する前にロケーションIDを検証するために必要です。

私が思いついたのは、モデルにbefore_addを追加することだけでした。

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

これは正しい方法ですか?もしそうなら、:check_location_ownershipはどのように見えるべきですか?または、関係の作成を防ぐためのより良い方法はありますか?

4

1 に答える 1

1

あなたがしたことは理にかなっていますが、私が考えることができる他の2つの方法があります。

1)関係:conditionsのオプションを使用します。has_many

2)カスタム検証方法。

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

場合によっては、個人的にこの3つから1つを選びます。

于 2013-03-25T10:39:47.593 に答える