Cocoon has_one协会破坏保存/更新使用邪恶的宝石 - Rails

问题描述:

我见过一些类似的问题,但没有涉及到与邪恶的多步使用Cocoon宝石格式与Rails的Gem。当我有has_many关联时,表单可以很好地保存,但是当有has_one关联(Client has_one doctor)时,记录似乎会保存并删除。花了这么长时间试图弄清楚,但只是不明白为什么会发生。Cocoon has_one协会破坏保存/更新使用邪恶的宝石 - Rails

class QuotesController < ApplicationController 
include Wicked::Wizard 
before_action :set_client, only: [:show, :update, :quote_success] 
steps :profile, :employment, :general_questions, :indemnity_details, :declarations 

def show 
    @client.build_doctor 
    @client.old_insurers.build 
    @client.practice_addresses.build 
    render_wizard 
end 

def update 
    @client.update(client_params) 
    render_wizard @client 
end 

def quote_success; end 

private 

def set_client 
    current_user = Client.find_by_id(session[:current_user_id]) 
    @client = current_user 
end 

def finish_wizard_path 
    if @client.valid? 
     ClientMailer.new_quote(@client).deliver 
     ClientMailer.new_quote_user_message(@client).deliver 
     end 
     quote_success_path 
    end 
end 

def client_params 
    params.require(:client).permit(:name, :email, :email_confirmation, :phone, :date_required, 
            :title, :first_name, :last_name, :date_of_birth, :nationality, :reg_body, 
            practice_addresses_attributes: [:id, :pa_line1, :pa_line2, :pa_line3, :pa_town, :pa_county, :pa_postcode, :other_practices, :_destroy], 
            old_insurers_attributes: [:id, :insurer, :oi_to, :oi_from, :oi_limit, :oi_excess, :oi_premium, :_destroy], 
            doctor_attributes: [:id, :gp_locum, :gp_locum_sessions, :gp_locum_locations]) 
    end 
    end 

客户端模式:

class Client < ActiveRecord::Base 
has_one :doctor, dependent: :destroy 
has_many :practice_addresses, dependent: :destroy 
has_many :callbks, inverse_of: :client 
has_many :old_insurers, dependent: :destroy 
accepts_nested_attributes_for :doctor 
accepts_nested_attributes_for :old_insurers, reject_if: :all_blank, allow_destroy: true 
accepts_nested_attributes_for :callbks 
accepts_nested_attributes_for :practice_addresses, reject_if: :all_blank, allow_destroy: true 
end 

医生型号:问题

class Doctor < ActiveRecord::Base 
    belongs_to :client 
end 

查看部分:

<%= simple_form_for @client, url: wizard_path do |f| %> 

<%= yield f %> 
.... 

<div id="doctors"> 
    <%= f.simple_fields_for :doctor do |gp| %> 
    <%= render 'doctor_fields', f: gp %> 
    <% end %> 
</div> 

Doctor_fields:

<div class="nested-fields"> 
<div class="panel panel-default"> 
    <div class="panel-heading"> 
     <strong>General Questions - GP</strong> 
    </div> 
    <div class="panel-body"> 

     <div class="table-responsive"> 
      <div class=bs-example data-example-id=striped-table> 
       <table class="table table-striped"> 
        <thead> 
         <tr> 
          <th>Are you a:</th> 
          <th>Yes/No</th> 
          <th>Number of Sessions per week</th> 
          <th>Number of Locations</th> 
         </tr> 
         <tr> 
          <td>Locum</td> 
          <td><%= f.input :gp_locum, as: :radio_buttons, checked: false, label: false %></td> 
          <td><%= f.input :gp_locum_sessions, label: false, required: false %></td> 
          <td><%= f.input :gp_locum_locations, label: false, required: false %></td> 
         </tr> 
      </div> 
    </table> 
</div> 
</div> 

登录:

Started GET "/quotes/employment" for ::1 at 2017-03-13 10:27:07 -0300 
Processing by QuotesController#show as HTML 
    Parameters: {"id"=>"employment"} 
    Client Load (1.6ms) SELECT "clients".* FROM "clients" WHERE   "clients"."id" = $1 LIMIT 1 [["id", 47]] 
    Doctor Load (1.1ms) SELECT "doctors".* FROM "doctors" WHERE "doctors"."client_id" = $1 LIMIT 1 [["client_id", 47]] 
    Rendered layouts/_quote_page_start.html.erb (2.0ms) 
    Rendered quotes/_doctor_fields.html.erb (234.4ms) 
    Rendered quotes/_form.html.erb (364.0ms) 
    Rendered layouts/_quote_page_mobile.html.erb (0.2ms) 
    Rendered quotes/employment.html.erb within layouts/application (423.2ms) 
    Rendered layouts/_shim.html.erb (0.1ms) 
    Profession Load (1.7ms) SELECT "professions".* FROM "professions" ORDER BY name ASC 
    Rendered layouts/_header.html.erb (8.6ms) 
    Rendered layouts/_footer.html.erb (11.4ms) 
Completed 200 OK in 1920ms (Views: 1845.1ms | ActiveRecord: 13.7ms) 


Started PATCH "/quotes/employment" for ::1 at 2017-03-13 10:27:21 -0300 
Processing by QuotesController#update as HTML 
    Parameters: {"utf8"=>"✓",  "authenticity_token"=>"7xvqW6SpbBgKy62zfdPclexYD9cxqNR/F8p+twW87F/vSz/5kmpRMCE59 LcL4taIclWj4ZeVQ6CRasqqy38iNw==", "client"=>{"profession_area"=>"General  Practicioner", "profession_area_other"=>"das", "doctor_attributes"=> {"gp_locum"=>"false", "gp_locum_sessions"=>"212", "gp_locum_locations"=>"21"},  "commit"=>"Next", "id"=>"employment"} 
    Client Load (2.0ms) SELECT "clients".* FROM "clients" WHERE "clients"."id" = $1 LIMIT 1 [["id", 47]] 
    (0.2ms) BEGIN 
     Doctor Load (0.5ms) SELECT "doctors".* FROM "doctors" WHERE  "doctors"."client_id" = $1 LIMIT 1 [["client_id", 47]] 
    SQL (0.6ms) INSERT INTO "doctors" ("gp_locum", "gp_locum_sessions", "gp_locum_locations", "client_id", "created_at", "updated_at") VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17, $18, $19, $20, $21, $22, $23, $24, $25, $26, $27, $28, $29, $30, $31, $32, $33, $34, $35) RETURNING "id" [["gp_locum", "f"], ["gp_locum_sessions", 212], ["gp_locum_locations", 21], ["client_id", 47], ["created_at", "2017-03-13 13:27:21.111656"], ["updated_at", "2017-03-13 13:27:21.111656"]] 
    (0.7ms) COMMIT 
    (0.7ms) BEGIN 
    (0.4ms) COMMIT 
Redirected to http://localhost:3000/quotes/general_questions 
Completed 302 Found in 38ms (ActiveRecord: 5.1ms) 


Started GET "/quotes/general_questions" for ::1 at 2017-03-13 10:27:21 -0300 
Processing by QuotesController#show as HTML 
    Parameters: {"id"=>"general_questions"} 
    Client Load (0.9ms) SELECT "clients".* FROM "clients" WHERE "clients"."id" = $1 LIMIT 1 [["id", 47]] 
    Doctor Load (0.4ms) SELECT "doctors".* FROM "doctors" WHERE "doctors"."client_id" = $1 LIMIT 1 [["client_id", 47]] 
    (0.1ms) BEGIN 
    SQL (0.8ms) DELETE FROM "doctors" WHERE "doctors"."id" = $1 [["id", 29]] 
    (0.5ms) COMMIT 

任何帮助将是巨大的感谢!如果你需要其他东西,请告诉我。

[注:约link_to_add_association和HAS_ONE一般性评论]

link_to_add_association将尝试在该协会建立一个新的项目。如果您有has_one关系,这实际上意味着它将取代现有的,如果有的话。

如果你真的需要link_to_add_association你可以尝试以下方法:

= link_to_add_association 'add doctor', @form_obj, :doctor, force_non_association_create: true 

(这将建立一个新的医生,但没有使用的关联,这可能意味着在关联定义不会被复制一些默认值,但现有的医生会不会被覆盖,除非打完选择保存形式)

[更新:你的情况]

刚从show方法去除@client.build_doctor 。每次调用医生时,都会重新初始化医生。我假设你只会在new方法中需要这个。

或者,如果我似乎正确地读,你只有一个show没有edit/new这样做

@client.build_doctor unless @client.doctor.present? 
+0

对不起,我这里有点糊涂了......我只希望客户能够有一位医生,因此我没有链接添加一位新医生的原因 - 我现在将添加我的完整视图代码 - 并使用has_one而不是has_many关联。 我确定这是我不太理解的东西,我的理解是,一旦用户完成了该表单页面并转到下一个表单,它应该保存医生,就是这样 - 作为客户端的单一关联? – DanRio

+0

对不起,我没有彻底地读过你的问题,因为'has_one'与cocoon/link_to_add_association有点混淆。看看你的代码,这不是导致医生“重置”的茧,而是你的'show'方法中的'build_doctor'行。相应地更新我的答案。 – nathanvda

+0

等一下,如果我正确读取,你也使用'show'作为'edit',对吧?再次更新我的答案。 – nathanvda