Cocoon has_one 协会打破 save/update 使用 Wicked Gem - Rails
Cocoon has_one association breaking upon save/update using Wicked Gem - Rails
我看到过一些与此类似的问题,但与在 Rails 中使用 Cocoon gem 和 Wicked 多步骤形式 Gem 无关。当我有一个 has_many 关联时,该表格保存良好,但当有一个 has_one 关联(客户 has_one 医生)时,该记录似乎保存然后删除。花了很长时间试图解决这个问题,但就是看不出为什么会这样。
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" = LIMIT 1 [["id", 47]]
Doctor Load (1.1ms) SELECT "doctors".* FROM "doctors" WHERE "doctors"."client_id" = 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" = LIMIT 1 [["id", 47]]
(0.2ms) BEGIN
Doctor Load (0.5ms) SELECT "doctors".* FROM "doctors" WHERE "doctors"."client_id" = 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 (, , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , ) 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" = LIMIT 1 [["id", 47]]
Doctor Load (0.4ms) SELECT "doctors".* FROM "doctors" WHERE "doctors"."client_id" = LIMIT 1 [["client_id", 47]]
(0.1ms) BEGIN
SQL (0.8ms) DELETE FROM "doctors" WHERE "doctors"."id" = [["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?
我看到过一些与此类似的问题,但与在 Rails 中使用 Cocoon gem 和 Wicked 多步骤形式 Gem 无关。当我有一个 has_many 关联时,该表格保存良好,但当有一个 has_one 关联(客户 has_one 医生)时,该记录似乎保存然后删除。花了很长时间试图解决这个问题,但就是看不出为什么会这样。
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" = LIMIT 1 [["id", 47]]
Doctor Load (1.1ms) SELECT "doctors".* FROM "doctors" WHERE "doctors"."client_id" = 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" = LIMIT 1 [["id", 47]]
(0.2ms) BEGIN
Doctor Load (0.5ms) SELECT "doctors".* FROM "doctors" WHERE "doctors"."client_id" = 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 (, , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , ) 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" = LIMIT 1 [["id", 47]]
Doctor Load (0.4ms) SELECT "doctors".* FROM "doctors" WHERE "doctors"."client_id" = LIMIT 1 [["client_id", 47]]
(0.1ms) BEGIN
SQL (0.8ms) DELETE FROM "doctors" WHERE "doctors"."id" = [["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?