2016-03-22 22 views
2

Aşağıdaki cevaplara baktığımı ve yine de bir çözümün işe yaramadığını söyleyerek bunu anlatacağım (ancak, bir şeyi gözden kaçırma ihtimalim göz önüne alındığında,) referans için de dahil olmak üzere:Ruby on Rails iç içe öznitelikleri kaydedilmiyor

Sorun açıklaması: Cue için iç içe geçmiş bir form içeren bir formum var. Form doğru bir şekilde oluşturulur ve Blok doğru şekilde kaydeder, ancak Cue Cue tablosunda görünmez, yani Cue, Blok gönderildiğinde kaydedilmez. Rails 4.2.5.1 kullanıyorum. Ayrıca gönderme konusunda herhangi bir hata yapmıyorum, bunu teşhis etmek biraz zorlaştırıyor.

Kodu:

_form.html.erb - Blok

<%= 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 

başka bir şey gerekiyorsa, lütfen bana bildirin! (Biçimlendirme büyük değilse de özür dilerim).

Herhangi bir yardım için çok teşekkür ederiz! Teşekkürler!!

Şu anda (yukarıda) blocks_controller.rb hat if @block.save hatayı undefined method 'encoding' for 7:Fixnum alıyorum 1

GÜNCELLEME. IngoAlbers (aşağıda) tarafından verilen cevaba göre aşağıdaki şeyleri değiştirdim ve yanıt here bulundu.

aşağıdaki şeyleri değiştirdik:

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 - bloklar

<%= 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 için çok teşekkürler Elp şimdiye kadar! Sanırım gerçekten yakınım!

GÜNCELLEME 2

yüzden Cue ve çalıştırmak için bir özellik olarak block_id ekledik aşağıdaki iki göçler:

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 

Hala hattında if @block.save yılında hatayı undefined method 'encoding' for 7:Fixnum alıyorum blocks_controller.rb.

+0

Eğer raylar konsolda işaret nesne oluşturmak için denediniz mi? Sadece aşağıdaki gibi hata ayıklamada yardımcı olmak için '@ cue' için bir doğrulama atabilir misiniz? Validates: cue_description, presence: true' ve formu gönderip gönderemeyeceğinize bakın. – Aloalo

+0

Lütfen cehaletime bu konuda izin verin ... Bu yüzden, hattınızı 'belongs_to' altındaki Cue modeline ekledim ve başka bir Block eklemeyi denedim. Parametreler geçildi ... Görüyorum "cues" => {"cue_code" => "", "cue_type_code" => "1" ... "cue_method_code" => ""} 've daha sonra 'İstenmeyen parametre: ipuçları'? – user3684314

cevap

2

Sorun, fields_for ürününüzün içinde olmalıdır. Muhtemelen olmalıdır:

<%= f.fields_for :cue do |ff| %>

Değil cues sadece biri olduğu için. O zaman ipucunu oluşturmalısın. Bu böyle örneğin, denetleyici veya doğrudan görünümünde ya da yapılabilir:

<%= f.fields_for :cue, @block.build_cue do |ff| %>

senin bloğunda sonra da cue_attributes olarak değiştirin ve aynı zamanda id izin vermeniz gerekir parametreler.

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_name]) 
end 

Ayrıca burada daha çok bilgi okuyabilir:

http://guides.rubyonrails.org/form_helpers.html#nested-forms

ikinci Güncelleme ilgili olarak:

İlk göç tip binary bir sütun block_id ekler. Bunun yerine kesinlikle integer olmalıdır. Bu, ilk geçişe bile gerek duymadığınızdan, ikinci geçişiniz 'u add_reference olarak değiştirirseniz, doğru şekilde ele alacağınız anlamına gelmez. Bu gibi görünmelidir:

class AddBelongsToToCues < ActiveRecord::Migration 
    def change 
    add_reference :cues, :block, index: true 
    add_foreign_key :cues, :blocks 
    end 
end 

add_reference ihtiyaçları biri block katı değil bir başvuru ekleyin. Bu daha sonra sizin için doğru sütunu oluşturacaktır.

Ayrıca bakınız: http://api.rubyonrails.org/classes/ActiveRecord/ConnectionAdapters/SchemaStatements.html#method-i-add_reference

+0

Çok teşekkürler! Sanırım cevaba yaklaşıyorum ... Şu andan itibaren tüm değişikliklerinizi uygulamamıştım ve Cue.' için bloklar # new ', özellikle 'bilinmeyen özniteliği' block_id 'ActiveRecord :: UnknownAttributeError alıyorum. . İz, '<% = f.fields_for: cue, @ block.build_cue do | ff | %> '. Sanırım "build_cue" kısmına atıfta bulunuyor ... – user3684314

+0

Bu, büyük olasılıkla 'belongs_to' derneği tarafından kullanılan' cues 'tablonuzda bir 'block_id' sütununun olmadığı anlamına gelir. Http://guides.rubyonrails.org/association_basics.html#the-belongs- tabloların nasıl görünmesi gerektiğine ve göçün istenen yapıyı oluşturmasına nasıl odaklanacağına bakın. – IngoAlbers

+0

Bunu yaptım ve hala hata alıyorum ...Bu hala devam ediyor gibi ikinci bir güncelleme gönderirim. – user3684314