Rails 3, CanCan, чтобы ограничить все результаты запросов по всему приложению на основе InstanceID пользователя - PullRequest
0 голосов
/ 07 сентября 2010

У меня есть две таблицы Пример пользователей (имя, адрес электронной почты, пароль, instance_id и т. Д.): James bond, james@abc.com, 1 Пример экземпляра (id, домен): 1, abc.com

В приложении я хочу убедиться, что Джеймс Бонд видит только те данные, которые назначены его экземпляру = 1

Так что, если у меня есть таблица книг с (name, desc, instance_id), он видит толькокниги его экземпляра.

Мне сказали, что CanCan - это то, что нужно, но я не вижу, как сделать что-то глобально, как указано выше, это похоже на роль администратора, модератора и т. д... Что мне нужно, но на уровне ниже, чем правила данных, упомянутые выше.

Мысли?

1 Ответ

3 голосов
/ 07 сентября 2010

вы можете попробовать использовать такие области как:

class Books < ActiveRecord::Base
# .... code ....
scope :personal, proc {|user| where(:instance_id => user.instance_id) }
# .... code ...
end

Теперь вы можете сделать:

@personal_books = Books.personal(@user)

Вы можете узнать больше об областях здесь: http://www.railsdispatch.com/posts/rails-3-makes-life-better (прокрутите внизчуть-чуть)

Другой способ - создать ассоциацию, такую ​​как

Пользователь has_many Книги через экземпляр

Тогда у вас будет дополнительный унаследованный пользователь, сопоставляющий таблицы с книгами поверх ихпример.Это отношение n: m.Таким образом, книга может принадлежать нескольким экземплярам.

Это выглядело бы так:

Таблица пользователей:

Пользователи (имя, адрес электронной почты, пароль, instance_id и т. Д ...)

Таблица книг:

Книги (name, desc) # не более instance_id!

Таблица сопоставления:

Назначения (instance_id, book_id)

И ваши модели будут выглядетьнапример:

class Assignment < ActiveRecord::Base
  belongs_to :book      # foreign key - book_id
  belongs_to :instance  # foreign key - instance_id
end

class Instance < ActiveRecord::Base
  has_many :assignments
  has_many :books, :through => :assignments
end

class Books < ActiveRecord::Base
  has_many :assignments
  has_many :users, :through => :assignments
end

class User < ActiveRecord::Base
  belongs_to :instance
end

Код для получения всех книг экземпляра пользователя будет выглядеть следующим образом:

@user       = User.find(:first)
@books      = @user.instance.books.find(:all)

(я рекомендую прочитать http://api.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html)

Редактировать

Вы можете попробовать это, если книга всегда принадлежит только одному экземпляру:

class User < ActiveRecord::Base
  belongs_to :instance
end


class Instance < ActiveRecord::Base
  has_many :users
  has_many :books
end


class Books < ActiveRecord::Base
  belongs_to :instance
end

Таким образом, вы получаете такие книги пользователя, как:

@user.instance.books.find(:all)
...