Ассоциация «принадлежит» с формой - PullRequest
0 голосов
/ 06 июля 2018

Этот вопрос о новом 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>
  1. Как вы можете видеть, параметр content_id не относится к параметру translation => hash, из-за чего мои сильные параметры не могут его найти. Есть ли лучший способ?

Во-вторых, это заставляет меня кодировать действие создания следующим образом:

@content = Content.find(params[:content_id])
@translation = @content.translations.build(translation_params)
  1. , что кажется неправильным, потому что я снова обхожу сильные параметры. Я знаю, что это чисто эстетическая проблема, и я не думаю, что это вредит безопасности или чему-то еще. Есть ли лучший способ?

Также моя форма выглядит так:

<%= form_with(model: @translation, url: [@content, @translation], local: true) do |form| %>
  1. К чему я в основном прибегал, прибегая к помощи проб и ошибок. Это лучшая практика?

1 Ответ

0 голосов
/ 06 июля 2018

ваш content_id отсутствует в хэше перевода по проекту Rails. Тем не менее, вы можете сделать следующее, чтобы немного почистить вещи

class TranslationsController < ApplicationController
  before_action :set_content, only: [:new, :create]

  def new
    @translation = @content.translations.new
  end

  def create
    @translation = @content.translations.build(translation_params)
    ...
  end

  private

  def set_content
    # use params.require to use strong params
    @content = Content.find(params.require(:content_id))
  end
end

если вы используете @content в других действиях, просто отрегулируйте фильтр before_action соответственно

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...