В моем приложении на Rails есть Пользователи.Пользователей просят указать их родной город и район / район.
class User < ActiveRecord::Base
belongs_to :city
belongs_to :district
end
class City < ActiveRecord::Base
has_many :users
has_many :districts
end
class District < ActiveRecord::Base
has_many :users
belongs_to :city
end
В формах я строю ассоциации, используя виртуальный атрибут в модели User, который принимает строку (дополнительную информацию ниже, если она уместна).
В консоли все это прекрасно работает, но в интерфейсе не работает.Кажется, проблема в том, что я могу получить city_name
через форму без проблем, но когда я пытаюсь назначить город и район в одной и той же форме, всегда происходит сбой.Другими словами, массовое назначение не работает.
@user.update_attributes(params[:user])
Вместо этого, единственное, что мне удалось выяснить, - это вручную установить каждую клавишу из отправки формы, например:
@user.name = params[:user][:name] if params[:user][:name]
@user.city_name = params[:user][:city_name] if params[:user][:city_name]
@user.district_name = params[:user][:district_name] if params[:user][:district_name]
Этот подход работает, но это боль, отчасти хрупкая, и он чувствует себя все неправильно, потому что он начинает нагнетать контроллер с большой логикой.
Мой вопрос:
Есть ли способ создания или обновления атрибутов в определенном порядке, в идеале в модели, чтобы контроллеру не приходилось беспокоиться обо всем этом?
Я делаю это неправильно?Если так, то какой подход был бы лучше.
Дополнительная информация
Вот как я строю ассоциации, используя виртуальные атрибуты для пользователямодель, в случае, если это имеет отношение к любым потенциальным ответчикам:
Я хочу, чтобы пользователи могли выбирать город, просто введя имя, например «Чикаго, Иллинойс».Это прекрасно работает, используя виртуальный атрибут в пользовательской модели, например:
def city_name
city.try :full_name
end
def city_name=(string)
self.city = City.find_or_create_by_location_string( string )
end
Для пользователя имеет смысл только найти или создать район из города, который он выбрал.Это работает немного по-другому:
def district_name
district.try :name
end
def district_name=(string)
if self.city.nil?
raise "Cannot assign a district without first assigning a city."
else
self.district = self.city.districts.find_or_create_by_name( string )
end
end
В слое модели эти вещи работают нормально, если заданы как city_name, так и district_name, а районная ассоциация работает, как и ожидалось.