Я собираюсь ответить на этот вопрос, предполагая, что эта форма предназначена для создания Game
, что belongs_to :user
, поскольку в форме есть user_id
, а user.city_of_birth
- строка.
Традиционный способ сделать это - использовать функцию Rails accepts_nested_attributes_for
.
https://api.rubyonrails.org/classes/ActiveRecord/NestedAttributes/ClassMethods.html
Однако , я настоятельно рекомендуючто вы рассматриваете возможность написания объекта формы , чтобы справиться с этим, чтобы ответственность за проверку правильности этой формы смешанной модели была полностью сохранена в одном месте.Я предлагаю использовать драгоценный камень, такой как Reform , чтобы упростить этот процесс.
# app/forms/games/new_game_form.rb
class Games::NewGameForm < Reform::Form
property :user_id, validates: { presence: true }
property :city_of_birth, virtual: true, validates: { presence: true }
property :game_name, validates: { presence: true }
def save
Game.transaction do
user.update!(city_of_birth: city_of_birth)
Game.create(user: user, game_name: game_name)
end
def user
@user ||= User.find(user_id)
end
end
Этот объект формы может затем использоваться вместо экземпляра Game
.
# GamesController
def new
@form = Games::NewGameForm.new(Game.new)
end
<!-- new.html.erb -->
<%= form_with @form, url: games_path, method: :post do |f| %>
<!-- your form fields -->
<% end %>
Обратите внимание, что очень нечетно кажется, что вы принимаете user_id
в форме, но также читаете city_of_birth
из @user
.Если @user
, для которого создается игра, уже известно (возможно, зарегистрированный пользователь), то бесполезно (и угроза безопасности) принимать идентификатор в форме - вы можете просто использовать тот же метод, который использовалсяустановить @user
.