2

我正在研究一個新的Rails 4應用程序,並且很難讓所有部分正確協同工作。我有一個與另一個模型(lat_long)belongs_to關聯的模型(樣本),並試圖從樣本視圖(編輯默認生成的視圖)對兩者執行CRUD操作。問題是lat_long可能是空白的;一切正常,如果它不是,但當它在模型中的驗證,所以我認爲它試圖保存一個空白的lat_long而不是將其設置爲零。更新和編輯是問題。保存belongs_to問題的Rails 4嵌套表單

下面是從代碼中的相關部分:
型號:

<%= form_for(@sample) do |f| %> 
    <%= f.fields_for :lat_long do |g| %> 
     <div class="field"> 
      <%= g.label :north_latitude %><br> 
      <%= g.text_field :north_latitude %> 
     </div> 
     <div class="field"> 
      <%= g.label :west_longitude %><br> 
      <%= g.text_field :west_longitude %> 
     </div> 
    <% end %> 
<% end %> 

samples_controller.rb:

class Sample < ActiveRecord::Base 
    belongs_to :lat_long 
    accepts_nested_attributes_for :lat_long 
end 

class LatLong < ActiveRecord::Base 
    validates_each :west_longitude do |record, attr, value| 
    record.errors.add attr, "must be within range." if (value < 110.0 or value > 115.0) 
    end 
    validates_each :north_latitude do |record, attr, value| 
    record.errors.add attr, "must be within range." if (value < 38.0 or value > 42.0) 
    end 
end 

樣品/ _form.html.erb在編輯和使用新

class SamplesController < ApplicationController 
# GET /samples/new 
    def new 
    @sample = Sample.new 
    @sample.build_lat_long 
    @sample.build_trap 
    end 
    # GET /samples/1/edit 
    def edit 
    @sample.lat_long || @sample.build_lat_long 
    @sample.trap || @sample.build_trap 
    end 
    # POST /samples 
    # POST /samples.json 
    def create 
    @sample = Sample.new(sample_params) 
    puts sample_params 
    respond_to do |format| 
     if @sample.save 
     format.html { redirect_to @sample, notice: 'Sample was successfully created.' } 
     format.json { render :show, status: :created, location: @sample } 
     else 
     format.html { render :new } 
     format.json { render json: @sample.errors, status: :unprocessable_entity } 
     end 
    end 
    end 
    # PATCH/PUT /samples/1 
    # PATCH/PUT /samples/1.json 
    def update 
    respond_to do |format| 
     if @sample.update(sample_params) 
     format.html { redirect_to @sample, notice: 'Sample was successfully updated.' } 
     format.json { render :show, status: :ok, location: @sample } 
     else 
     format.html { render :edit } 
     format.json { render json: @sample.errors, status: :unprocessable_entity } 
     end 
    end 
    end 
    def sample_params 
    params.require(:sample).permit(..., 
            lat_long_attributes: [:id, 
            :west_longitude, :north_latitude]) 
    end 
end 

我可以在更新之前檢查控制器當然,但這是正確的做法嗎?它「覺得」應該有一種讓Rails處理這個問題的方法,但是看到大量的StackOverflow問題和文檔沒有給出任何想法。大多數例子使用has_one或has_many,所以我不知道這是否是問題?根據this question,belongs_to與accep_nested_attributes_for一起工作很新穎,所以也許這只是簡單的沒有爲此設置。

我想知道什麼是最好的做法是這種情況下,最「Railsy」的事情。哦,我想我已經包含了所有相關的代碼,但是如果還有其他東西需要讓我知道。

回答

1

我會做這樣的事情:

class Sample < ActiveRecord::Base 
    belongs_to :lat_long 
    accepts_nested_attributes_for :lat_long, reject_if: proc { |attributes| attributes['west_longitude'].blank? && attributes['north_latitude'].blank? } 
end 

class LatLong < ActiveRecord::Base 
    validates :west_longitude, numericality: { greater_than_or_equal_to: 110, 
          less_than_or_equal_to: 115, 
          message: "must be within range" }, 
          allow_nil: true 

    validates :north_latitude, numericality: { greater_than_or_equal_to: 38, 
          less_than_or_equal_to: 42, 
          message: "must be within range" }, 
          allow_nil: true 
end 
+0

這將導致一個空白lat_long(除ID,的updated_at,created_at空)被保存。我希望sample.lat_long本身爲零(因此數據庫中的sample.lat_long_id爲NULL)。 – Maltiriel

+0

@Maltiriel剛剛修改了答案,看看是否有幫助。我想你也可以去除驗證的':allow_nil => true'選項,因爲沒有空值將以這種方式到達模型。 –

+0

是的,我想像你的答案的第二部分可以工作,但我不知道它是否是最好的設計。但感謝您的答案。至於你對剝離的評論:allow_nil => true,我不知道你在那裏做什麼。如果該行不在或者如果是:allow_nil => false,那麼視圖需要這些值。他們被允許是空白的,我只是不希望空白對象被保存到數據庫。 – Maltiriel