Это вопрос Rails / ActiveRecord.
У меня есть модель, которая в основном должна представлять события или выступления. Каждое событие имеет много атрибуций : атрибуция - это что-то вроде "В этом случае у Лица X была роль Y".
Я пришел к выводу, что лучший способ разрешить пользователю редактировать эти данные - предоставить поле с произвольным текстом, которое ожидает структурированный формат, который я назову строку роли :
singer: Elvis Costello, songwriter: Paul McCartney, ...
где я использую автозаполнение, чтобы завершить как имена ролей (певец, автор песен ...), так и имена людей. И роли, и люди хранятся в базе данных.
Чтобы реализовать это, я создал виртуальный атрибут в модели событий:
def role_string
# assemble a role string from the associations in the model
end
def role_string=(s)
# parse a string in the above role string format,
# look up the People and Events mentioned, and update
# what's in the database
end
Это все хорошо. Все это работает довольно хорошо, когда строка роли правильно сформирована и все ассоциации, заданные строкой роли, проверяются.
Но что, если строка роли деформирована? Хорошо, я полагаю, я могу просто использовать регулярное выражение вместе со стандартной проверкой для проверки формата:
validates_format_of :role_string, :with => /(\w+:\s*\w+)(,\s*\w+:\s*\w+)*/
Но что, если ассоциации, подразумеваемые строкой роли, недействительны? Например, что произойдет, если я приведу приведенную выше строку роли, а Elvis Costello
не ссылается на действующего человека?
Я подумал, ну, я мог бы использовать validates_each
для атрибута :role_string
, чтобы найти ассоциации и выдать ошибку, если, например, одно из приведенных имен не совпадает ни с чем.
У меня два вопроса: во-первых, мне не нравится этот подход, так как для проверки ассоциаций мне нужно было бы проанализировать строку и найти их, что дублирует то, что я буду делать в самом role_string=
, кроме для фактического сохранения ассоциаций в базе данных.
Во-вторых, ... как бы я указал, что при присвоении этого виртуального атрибута произошла ошибка?