Подтвердить что ты не робот

Rails - как я могу проверить существование строки, на которую ссылается внешний ключ

Учитывая, что "Rails Way", похоже, не использует ограничения внешнего ключа, я ищу альтернативу, которая позволит мне проверить, что строка, связанная с внешними ключами, действительно существует в TableA, прежде чем я сохраню объект в TableB с table_a_id.

Единственный ресурс, который я нашел, чтобы сделать это до сих пор (не могу найти ссылку на сообщение в блоге, о котором он упоминал, был датирован 2007 годом), похоже, не совместим с Rails 3.2, так что кто-нибудь может предложить способ сделать это?

В настоящее время я смотрю на создание валидатора, чтобы вручную назначать соответствующие атрибуты в моих моделях, но я не могу решить, как это сделать с помощью validate_each (объект, атрибут, значение).

4b9b3361

Ответ 1

Существует плагин, который поможет вам в этом для ассоциаций принадлежать_to: Проверяет существование. Но, может быть, вы можете добавить свою собственную проверку? Что-то вроде этого:

# Assuming your foreign key is user_id (which references the table User)
validate :user_id_exists

def user_id_exists
  return false if User.find_by_id(self.user_id).nil?
end

Ответ 2

просто используйте, как показано ниже,

validates :user, presence: true

Он автоматически проверяет наличие записи пользователя в db.

Ответ 3

У меня были проблемы с этим фрагментом кода:

return false if User.find(self.user_id).nil?

Мне пришлось поймать исключение ActiveRecord, если не найдено подходящей записи. nil? не работает, когда запись не найдена; исключение создается до выполнения nil?.

# Assuming your foreign key is user_id (which references the table User)
validate :user_id_exists

def user_id_exists
  begin
    User.find(self.user_id)
  rescue ActiveRecord::RecordNotFound
    errors.add(:user_id, "user_id foreign key must exist")
    false
  end
end

Это полезно, если вы используете недопустимые? утверждения в модульных тестах.

request.user_id = unknown
assert request.invalid?

request.user_id = 1
assert request.valid?

Ответ 4

Обратите внимание, что с Rails 3.2, validates_presence_of работает точно так, как вы хотите, в этом случае, и вам не нужно создавать сложную структуру, такую ​​как вышеупомянутые ответы, или даже использовать хороший validates_existence_of gem.

Ответ 5

Мне не нравятся исключения. Я решил эту проблему, выполнив следующие действия:

class Foo < ActiveRecord::Base

    validate :bar_exists

    protected

    def bar_exists
        if !User.where(bar_id: self.bar_id).exists? then
            errors.add(:bar_id, 'A valid bar_id is valid.')
        end
    end

end

Ответ 6

Вам нужно указать опцию inverse_of и подтвердить, что оно истинно.

В Руководство по проверке активной записи:

Чтобы проверить связанные записи, присутствие которых необходимо, вы должны указать опцию : inverse_of для ассоциации