Я предоставлю это, сказав, что я рассмотрел следующие ответы и до сих пор не ударил решение, которое работает (однако, учитывая возможность, я мог бы что-то упустить, я в том числе их для справки):Вложенные атрибуты в Ruby on Rails не сохраняются
- Ruby on Rails - Not saving User - Nested Attributes and Nested Forms
- Nested Attributes in ruby on rails
- Ruby on Rails nested attributes not saving into database?
- Nested attributes not saving in database? Does not display values - Ruby on Rails
Описание проблемы: У меня есть форма Block с вложенной формой для Cue. Форма корректно отобразится, и блок сохранит правильно, но Cue не отображается в таблице Cue, т. Е. Cue не сохраняется при отправке блока. Я использую Rails 4.2.5.1. Я также не получаю никаких ошибок при отправке, что затрудняет диагностику.
Код:
_form.html.erb - блок
<%= form_for(@block) do |f| %>
<% if @block.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(@block.errors.count, "error") %> prohibited this block from being saved:</h2>
<ul>
<% @block.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="field hidden">
<%= f.label :block_code, class: "hidden" %><br>
<%= f.text_field :block_code, class: "form-control hidden" %>
</div>
<div class="field">
<%= f.label :block_duration %><br>
<div class="input-group">
<%= f.number_field :block_duration, class: 'text_field form-control', :step => 'any' %>
<div class="input-group-addon">seconds</div>
</div>
</div>
<div class="field">
<label>Does this block have a cue associated with it?</label>
<input type="radio" name="cue" value="cueYes" data-type="cueYes" data-radio="cue"> Yes
<input type="radio" name="cue" value="cueNo" data-type="cueNo" data-radio="cue" checked> No
<div class="field" id="cueYes">
<%= f.fields_for :cues do |ff| %>
<div class="field hidden">
<%= ff.label :cue_code, class: "hidden" %><br>
<%= ff.text_field :cue_code, class: "hidden" %>
</div>
<div class="field">
<%= ff.label "Cue Type" %><br>
<%= ff.collection_select(:cue_type_code, CueType.all, :cue_type_code, :cue_type_name, {prompt: "Select a cue type..."}, {class: "form-control"}) %>
</div>
<div class="field">
<%= ff.label "Cue Description" %><br>
<%= ff.text_area :cue_description, class: "form-control" %>
</div>
<div class="field">
<%= ff.label "Cue Method" %><br>
<%= ff.collection_select(:cue_method_code, CueMethod.all, :cue_method_code, :cue_method_name, {prompt: "Select a cue method..."}, {class: "form-control"}) %>
</div>
<% end %>
</div>
</div>
<div class="field">
<%= f.label "Location" %><br>
<%= collection_select :block, :location_code, Location.all, :location_code, :location_name, {prompt: "Select a location..."}, {class: "form-control"} %>
</div>
<div class="field">
<%= f.label "Scene" %><br>
<%= collection_select :block, :scene_code, Scene.all, :scene_code, :actAndScene, {prompt: "Select a scene..."}, {class: "form-control"} %>
</div>
<div class="field">
<%= f.label "Block Description" %><br>
<%= f.text_area :block_description, class: "form-control" %>
</div>
<div class="actions">
<%= f.submit "Create Block", class: "btn btn-primary" %>
</div>
<% end %>
blocks_controller.rb
class BlocksController < ApplicationController
before_action :set_block, only: [:show, :edit, :update, :destroy]
# GET /blocks
# GET /blocks.json
def index
@blocks = Block.all
end
# GET /blocks/1
# GET /blocks/1.json
def show
end
# GET /blocks/new
def new
@block = Block.new
# Set block code as next integer after max block code.
@block.block_code = (Block.maximum(:block_code).to_i.next).to_s(2)
end
# GET /blocks/1/edit
def edit
end
# POST /blocks
# POST /blocks.json
def create
@block = Block.new(block_params)
respond_to do |format|
if @block.save
format.html { redirect_to @block, notice: 'Block was successfully created.' }
format.json { render :show, status: :created, location: @block }
else
format.html { render :new }
format.json { render json: @block.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /blocks/1
# PATCH/PUT /blocks/1.json
def update
respond_to do |format|
if @block.update(block_params)
format.html { redirect_to @block, notice: 'Block was successfully updated.' }
format.json { render :show, status: :ok, location: @block }
else
format.html { render :edit }
format.json { render json: @block.errors, status: :unprocessable_entity }
end
end
end
# DELETE /blocks/1
# DELETE /blocks/1.json
def destroy
@block.destroy
respond_to do |format|
format.html { redirect_to blocks_url, notice: 'Block was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_block
@block = Block.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def block_params
params.require(:block).permit(:block_code, :block_duration, :cue_code, :location_code, :scene_code, :block_description, :cues_attributes => [:cue_code, :cue_type_code, :cue_description, :cue_method_name])
end
end
block.rb
class Block < ActiveRecord::Base
has_one :cue, -> { where processed: true }
accepts_nested_attributes_for :cue, allow_destroy: true
end
cue.rb
class Cue < ActiveRecord::Base
belongs_to :block
end
cues_controller.rb
class CuesController < ApplicationController
before_action :set_cue, only: [:show, :edit, :update, :destroy]
# GET /cues
# GET /cues.json
def index
@cues = Cue.all
end
# GET /cues/1
# GET /cues/1.json
def show
end
# GET /cues/new
def new
@cue = Cue.new
# Set cue code as next integer after max cue code.
@cue.cue_code = (Cue.maximum(:cue_code).to_i.next).to_s(2)
end
# GET /cues/1/edit
def edit
end
# POST /cues
# POST /cues.json
def create
@cue = Cue.new(cue_params)
respond_to do |format|
if @cue.save
format.html { redirect_to @cue, notice: 'Cue was successfully created.' }
format.json { render :show, status: :created, location: @cue }
else
format.html { render :new }
format.json { render json: @cue.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /cues/1
# PATCH/PUT /cues/1.json
def update
respond_to do |format|
if @cue.update(cue_params)
format.html { redirect_to @cue, notice: 'Cue was successfully updated.' }
format.json { render :show, status: :ok, location: @cue }
else
format.html { render :edit }
format.json { render json: @cue.errors, status: :unprocessable_entity }
end
end
end
# DELETE /cues/1
# DELETE /cues/1.json
def destroy
@cue.destroy
respond_to do |format|
format.html { redirect_to cues_url, notice: 'Cue was successfully destroyed.' }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_cue
@cue = Cue.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def cue_params
params.require(:cue).permit(:cue_code, :cue_type_code, :cue_description, :cue_method_code)
end
end
Если что-то еще нужно, пожалуйста, дайте мне знать! (Также жаль, если форматирование не очень велико).
Любая помощь очень ценится !! Благодаря!!
UPDATE 1
В настоящее время я получаю ошибку undefined method 'encoding' for 7:Fixnum
на линии if @block.save
в blocks_controller.rb
(выше). Я изменил следующие вещи, основываясь на ответе, указанном IngoAlbers
(см. Ниже), и ответ найден here.
Я изменил следующие вещи:
blocks_controller.rb
def block_params
params.require(:block).permit(:block_code, :block_duration, :cue_code, :location_code, :scene_code, :block_description, :cue_attributes => [:id, :cue_code, :cue_type_code, :cue_description, :cue_method_code])
end
_form.html.erb - блоки
<%= f.fields_for :cue, @block.build_cue do |ff| %>
block.rb
class Block < ActiveRecord::Base
has_one :cue
accepts_nested_attributes_for :cue, allow_destroy: true
end
Большое спасибо за h elp до сих пор! Я думаю, что я действительно рядом!
UPDATE 2
Так я добавил block_id
как атрибут перемотать и запустить следующие две миграции:
class AddBlockIdToCues < ActiveRecord::Migration
def self.up
add_column :cues, :block_id, :binary
end
def self.down
remove_column :cues, :block_id
end
end
class AddBelongsToToCues < ActiveRecord::Migration
def change
add_reference :cues, :blocks, index: true
add_foreign_key :cues, :blocks
end
end
Я все еще получаю ошибку undefined method 'encoding' for 7:Fixnum
на линии if @block.save
в blocks_controller.rb
.
Вы пытались создать объект кием в консоли рельсы? Можете ли вы использовать некоторую проверку для '@ cue', чтобы помочь с отладкой , например' validates: cue_description, presence: true' и посмотреть, можете ли вы отправить форму. – Aloalo
Прошу извинить мое невежество в этом ... Поэтому я добавил вашу линию к модели Cue под 'own_to' и попробовал добавить еще один блок. Параметры передаются ... Я вижу '' cues '=> {"cue_code" => "", "cue_type_code" => "1" ... "cue_method_code" => ""} ', а затем после этого 'Неперечисленный параметр: cues'? – user3684314