使用Wicked Gem - Rails保存/更新Cocoon has_one关联

时间:2017-03-13 13:34:08

标签: ruby-on-rails simple-form cocoon-gem wicked-gem

我已经看到了一些类似的问题,但没有任何关于使用Cocoon宝石与Wicked多步形式Gem in Rails。当我有一个has_many关联时,表单保存正常但是当有一个has_one关联(Client has_one doctor)时,记录似乎保存然后删除。花了这么长时间试图解决这个问题但却无法理解为什么会发生这种情况。

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

Doctor Model:

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

任何帮助都会非常感谢!!如果您还有其他需要,请告诉我。

1 个答案:

答案 0 :(得分:2)

[注意:关于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

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

[更新:在您的情况下]

只需从@client.build_doctor方法中删除show即可。这会在每次呼叫时重新初始化医生。我假设你只想在new方法中使用它。

或者,如果我似乎读得正确,您只有show而没有edit/new做类似

的事情
@client.build_doctor unless @client.doctor.present?