Этот вопрос о новом form_with помощнике в Rails. Конкретный случай, когда форма предназначена для модели, которая принадлежит_ другой. Вот некоторый код.
routes.rb
resources :contents do
resources :translations
end
Миграция
class CreateTranslations < ActiveRecord::Migration[5.2]
def change
create_table :translations do |t|
t.text :translation
t.string :to_lang
t.references :content, foreign_key: true, dependent: :delete
t.timestamps
end
end
end
Форма
<%= form_with(model: @translation, url: [@content, @translation], local: true) do |form| %>
<% if translation.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(translation.errors.count, "error") %> prohibited this translation from being saved:</h2>
<ul>
<% translation.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field">
<%= form.label "Target Language", class: "label" %>
<div class="select">
<%= form.select(:to_lang, options_for_select([["English", "en"], ["French", "fr"], ["Spanish", "es"]])) %>
</div>
</div>
<div class="field">
<%= form.label "Original Content" %>
<%= form.label translation.content.text %>
</div>
<div class="actions">
<%= form.submit %>
</div>
<% end %>
Translation_controller.rb
def new
@content = Content.find(params[:content_id])
@translation = @content.translations.new
end
def create
@content = Content.find(params[:content_id])
@translation = @content.translations.build(translation_params)
respond_to do |format|
if @translation.save
format.html { redirect_to contents_path, notice: 'Translation was successfully created.' }
format.json { render :show, status: :created, location: @translation }
else
format.html { render :new }
format.json { render json: @translation.errors, status: :unprocessable_entity }
end
end
end
Вопросы
Этот код работает, но я думаю, что могу его улучшить. Когда я смотрю на параметры в действии создания, я вижу это:
<ActionController::Parameters {"utf8"=>"✓", "authenticity_token"=>"dFdTw+d85qA2BsLb0OW4TcaVfkMIaNEYgXcPvE8ff5ANprfoL58clGlx5kSC5zzoSOM0nSf9kaNvH8ebpUj5JQ==", "translation"=>{"to_lang"=>"en"}, "commit"=>"Create Translation", "controller"=>"translations", "action"=>"create", "content_id"=>"1"} permitted: false>
- Как вы можете видеть, параметр content_id не относится к параметру translation => hash, из-за чего мои сильные параметры не могут его найти. Есть ли лучший способ?
Во-вторых, это заставляет меня кодировать действие создания следующим образом:
@content = Content.find(params[:content_id])
@translation = @content.translations.build(translation_params)
- , что кажется неправильным, потому что я снова обхожу сильные параметры. Я знаю, что это чисто эстетическая проблема, и я не думаю, что это вредит безопасности или чему-то еще. Есть ли лучший способ?
Также моя форма выглядит так:
<%= form_with(model: @translation, url: [@content, @translation], local: true) do |form| %>
- К чему я в основном прибегал, прибегая к помощи проб и ошибок. Это лучшая практика?