Как волшебным образом снабдить области активных записей аргументами?

#ruby #activerecord #scope #syntactic-sugar #database-relations

#ruby #activerecord #область #синтаксический-сахар #отношения между базой данных

Вопрос:

Я не уверен, что это вообще возможно, но давайте посмотрим, придумает ли кто-нибудь из вас решение. Это более или менее касается качества кода с точки зрения удобочитаемости, а не актуальной проблемы, потому что у меня уже есть решение. У меня есть модель дружбы и модель пользователя. Модель дружбы используется для моделирования дружеских отношений между двумя пользователями:

 class Friendship

  def self.requested(user)
    where(:user_id => user).where(:status => 'requested')
  end

  def self.pending(user)
    where(:user_id => user).where(:status => 'pending')
  end

  def self.accepted(user)
    where(:user_id => user).where(:status => 'accepted')
  end

  # ...

end

class User
   has_many :friendships

   # ...
end
  

Возможно ли каким-либо образом вызвать запрошенную, ожидающую или принятую область через
пользовательская модель без предоставления аргумента?

 a_user.friendships.pending # this does not work, is there a way to get it working?

a_user.friendships.pending(a_user) # works of course!
  

Комментарии:

1. Я почти уверен, что это уже работает таким образом. Просто удалите пользовательские части методов области по дружбе.

Ответ №1:

Я думаю, это должно сработать, если вы уберете аргумент. Подобный вызов отложенного отключения пользовательского объекта уже должен охватывать дружеские отношения с соответствующим пользователем. Определите метод следующим образом:

 def self.pending
  where(:status => 'pending')
end
  

И вызвать:

 a_user.friendships.pending
  

Проверьте журналы для сгенерированного запроса, если вы не уверены, что он работает.

Если вы все еще хотите вызвать его, передав аргумент, я бы назвал этот метод Friendship.pending_for(user) .

Комментарии:

1. Потрясающе! Я должен был попробовать это первым. Иногда я недооцениваю магию Active Record. Работает как по волшебству. Большое спасибо.

2. Кстати, вместо определения метода я теперь просто использовал scope :pending, where(:status => 'pending') .

3. Будьте с этим немного осторожны. Использование способа ‘scope’ приводит (или использовалось для того, чтобы вызывать) Arel для поиска столбца состояния во время загрузки класса. Итак, если вы ввели столбец в миграции, которая еще не выполнялась, материал ломается. лямбда-области или методы класса, по-видимому, являются лучшим способом избежать этого.