#ruby-on-rails #rails-activerecord #has-and-belongs-to-many
#ruby-on-rails #rails-activerecord #имеет и принадлежит многим
Вопрос:
В моей модели Rails есть несколько плохих строк. Как правило, первая ошибка возникает при обращении roles
к переменной из has_access
def. И затем, во-вторых, при выполнении where
действия.
class Organization < ActiveRecord::Base
has_and_belongs_to_many :organizations_users
belongs_to :user
validates :name, :presence => true, :length => { minimum: 4, maximum: 35 }, uniqueness: true
roles = { :administrator => 1, :support => 2 }
def has_access(chosen_user, role)
self.organizations_users.where('user_id = ? and role = ?', chosen_user.id, roles[role]).exists?
end
def add_user(chosen_user, role)
if !self.has_access(chosen_user, role)
self.organizations_users.create({user_id: chosen_user.id, role: roles[role]})
end
has_access(chosen_user,role)
end
end
Мне также нужно выполнить запрос по organizations_users
таблице, чтобы получить информацию о доступе. Как я могу это исправить?
Комментарии:
1. … В чем ошибка?
2. Для оператора where (2-й) — это «неопределенные
where' for #<Organization:0x4892898>". For roles is undefined local variable or method
роли методов» для #<Организация: 0x47b0038>3. Что вы хотите сделать? Объясните, что вы ожидаете от этого метода.
4. Мне нужно иметь метод, который будет доступен как внутри класса, так и в экземпляре. Я хочу, чтобы эти методы возвращали, имеет ли пользователь доступ к организации и добавляет пользователя в организацию.
5. Разве вы не можете превратить этот has_access в область видимости? Тогда вы бы ссылались на него как
!Organization.has_access(chosen_user, role)
Ответ №1:
Самым простым решением было бы изменить
def has_access(chosen_user, role)
where('user_id = ? and role = ?', chosen_user.id, roles[role]).exists?
end
Для:
def has_access(chosen_user, role)
Organization.where('user_id = ? and role = ?', chosen_user.id, roles[role]).exists?
end
Причина этого в том, что метод where() является методом класса и доступен только из самого класса, Organization.where
т. Е. . Кстати, я предполагаю (опасно :)), что это предложение where используется из Организации.
Ответ №2:
Чтобы найти или добавить организацию, выполните следующие действия:
def has_access(role)
self.organizations_user.find_or_create_by_role(role)
end
Это позволит вам использовать:
user = User.has_access("administrator")
user = User.first.has_acess("administrator")
И сделает поиск в таблице user_organizations или создаст новую запись, если не сможет ее найти. Отношение ActiveRecord позаботится об идентификаторе пользователя
Комментарии:
1. Но тогда он недоступен, как
user_access = User.first.has_access...
2. Это потому, что User.first возвращает один экземпляр, а затем вы пытаетесь выполнить .where, который является методом класса для массивов.
3. Однако это самостоятельно. не работает, попробовал сейчас. Мне нужно иметь метод, который будет доступен как внутри класса, так и в экземпляре
4.
def self.*
создает организацию.* метод класса. Подумайте о статических методах на статически скомпилированном языке. Вы не можете вызвать self.*, вам придется вызвать Organization .*5. Попробуйте сделать это до тех пор, пока has access является логическим значением.