Правильные методы в модели Ruby on Rails

#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 является логическим значением.