Rails 关联没有保存到数据库
Rails associations doesn't save to db
我有这个设置,但是当我试图拯救一个从业者时,注释被保存到数据库中。
table 是用户、诊所和从业者。用户应该能够创建多个诊所,每个诊所应该能够向特定诊所添加多个从业者。
我从日志中得到这个错误
Started PUT "/registration_steps/practitioners_general" for ::1 at 2020-03-01 11:59:29 +0100
Processing by RegistrationStepsController#update as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"KGwLxzNk96QEiY8Enun4cK3Gd3ec0GFsJxFxIq75MDQEGVcpapxTfh7aHR6slMojd3+hQg4MevmPDewRq7vGiA==", "user"=>{"clinics_attributes"=>{"0"=>{"practitioners_attributes"=>{"1583060279301"=>{"practitioner_first_name"=>"sdsad", "practitioner_last_name"=>"sdsadsa", "practitioner_description"=>"sadasda", "practitioner_mail"=>"kvnirvana@yahoo.dk", "practitioner_phone"=>"24210886", "practitioner_website"=>""}}, "id"=>"7"}}}, "commit"=>"Gem", "id"=>"practitioners_general"}
User Load (1.9ms) SELECT `users`.* FROM `users` WHERE `users`.`id` = 95 ORDER BY `users`.`id` ASC LIMIT 1
↳ app/controllers/registration_steps_controller.rb:17
Unpermitted parameter: :practitioners_attributes
(0.2ms) BEGIN
↳ app/controllers/registration_steps_controller.rb:19
Clinic Load (0.5ms) SELECT `clinics`.* FROM `clinics` WHERE `clinics`.`user_id` = 95 AND `clinics`.`id` = 7
↳ app/controllers/registration_steps_controller.rb:19
(1.4ms) COMMIT
↳ app/controllers/registration_steps_controller.rb:19
(0.9ms) BEGIN
↳ app/controllers/registration_steps_controller.rb:20
(0.2ms) COMMIT
↳ app/controllers/registration_steps_controller.rb:20
Redirected to http://localhost:3000/registration_steps/practitioners_professions
Completed 302 Found in 18ms (ActiveRecord: 5.1ms)
Started GET "/registration_steps/practitioners_professions" for ::1 at 2020-03-01 11:59:29 +0100
Processing by RegistrationStepsController#show as HTML
Parameters: {"id"=>"practitioners_professions"}
User Load (0.4ms) SELECT `users`.* FROM `users` WHERE `users`.`id` = 95 ORDER BY `users`.`id` ASC LIMIT 1
↳ app/controllers/registration_steps_controller.rb:12
Rendering registration_steps/practitioners_professions.html.erb within layouts/application
Profession Load (0.5ms) SELECT `professions`.* FROM `professions` INNER JOIN `user_professions` ON `professions`.`id` = `user_professions`.`profession_id` WHERE `user_professions`.`user_id` = 95
↳ app/views/registration_steps/practitioners_professions.html.erb:47
Profession Load (0.4ms) SELECT `professions`.* FROM `professions`
↳ app/views/registration_steps/practitioners_professions.html.erb:47
Speciality Load (0.5ms) SELECT `specialities`.* FROM `specialities` INNER JOIN `user_specialities` ON `specialities`.`id` = `user_specialities`.`speciality_id` WHERE `user_specialities`.`user_id` = 95
↳ app/views/registration_steps/practitioners_professions.html.erb:62
Speciality Load (0.3ms) SELECT `specialities`.* FROM `specialities`
↳ app/views/registration_steps/practitioners_professions.html.erb:62
Service Load (0.3ms) SELECT `services`.* FROM `services` WHERE `services`.`user_id` = 95
↳ app/views/registration_steps/practitioners_professions.html.erb:81
Rendered services/_services_fields.html.erb (7.5ms)
Rendered services/_services_fields.html.erb (6.4ms)
Rendered registration_steps/practitioners_professions.html.erb within layouts/application (34.6ms)
Rendered layouts/_header.html.erb (4.1ms)
Rendered layouts/_footer.html.erb (0.7ms)
Completed 200 OK in 92ms (Views: 88.0ms | ActiveRecord: 2.4ms)
到目前为止,我就是这样尝试让它工作的:
用户有很多诊所
诊所属于用户
诊所有很多从业者
从业者属于诊所
我添加了一个外国用户密钥来连接诊所 table 与用户 table
我已经添加了一个外国诊所密钥来连接从业者 table 和诊所 table
user.rb
class User < ApplicationRecord
has_many :clinics, dependent: :destroy
accepts_nested_attributes_for :clinics, reject_if: :all_blank, allow_destroy: true
end
clinic.rb
class Clinic < ApplicationRecord
belongs_to :user
has_many :practitioners
accepts_nested_attributes_for :practitioners, reject_if: :all_blank, allow_destroy: true
end
practitioner.rb
class Practitioner < ApplicationRecord
belongs_to: clinic
end
为从业者添加诊所外键
class AddClinicReferenceToPratitioners < ActiveRecord::Migration[5.2]
def change
add_reference :practitioners, :clinic, foreign_key: true
end
end
将用户外键添加到诊所
class AddUserReferenceToClinics < ActiveRecord::Migration[5.2]
def change
add_reference :clinics, :user, foreign_key: true
end
end
practitioners_general.html.rb
<div class="content">
<div class="content practitioner">
<h2 class="page-title">Generel information</h2>
<%= simple_form_for @user, url: wizard_path, method: :put do |f| %>
<%= f.simple_fields_for(:clinics) do |p| %>
<%= render 'clinics/clinics_fields', :f => p %>
<% end %>
<div class="submit-container">
<%= f.submit "Gem", :class => 'btn blue' %>
</div>
<% end %>
</div>
</div>
clinics/_clinics_fields.html.erb
<%= f.simple_fields_for(:practitioners) do |p| %>
<%= render 'practitioners/practitioners_fields', :f => p %>
<% end %>
<div class="links">
<%= link_to_add_association 'Add Practitioner', f, :practitioners, :partial => 'practitioners/practitioners_fields' %>
</div>
practitioners/practitioners_fields.html.erb
<div class="nested-fields">
<div class="basic-section">
<div class="info-group">
<div class="field-group">
<div class="field text-field">
<%= f.input_field :practitioner_first_name, required: true, autofocus: true, autocomplete: "Fornavn", placeholder: "Fornavn" %>
</div>
<div class="field text-field">
<%= f.input_field :practitioner_last_name, required: true, autofocus: true, autocomplete: "Efternavn", placeholder: "Efternavn" %>
</div>
</div>
</div>
</div>
<div class="about-section">
<div class="field text-field">
<%= f.input_field :practitioner_description, :as => :text, :input_html => { 'rows' => 5}, autofocus: true, autocomplete: "Beskrivelse af behandler", placeholder: "Beskrivelse af behandler" %>
</div>
</div>
<div class="field-group contact-section">
<div class="field text-field">
<%= f.input_field :practitioner_mail, input_html: { autocomplete: 'email' }, autofocus: true, placeholder: "E-mail" %>
</div>
<div class="field text-field">
<%= f.input_field :practitioner_phone, autofocus: true, autocomplete: "Tlf. nr.", placeholder: "Tlf. nr." %>
</div>
<div class="field text-field">
<%= f.input_field :practitioner_website, required: false, autofocus: true, autocomplete: "Hjemmeside", placeholder: "Hjemmeside" %>
</div>
</div>
</div>
registration_steps_controller.rb
class RegistrationStepsController < ApplicationController
include Wicked::Wizard
steps :company_general, :company_images, :practitioners_general, :practitioners_professions, :practitioners_educations
def create
@practitioner = Practitioner.new(params[:practitioners])
@practitioner.save
end
def show
@user = current_user
render_wizard
end
def update
@user = current_user
# Change @user.attributes(user_params) by @user.update_attributes(user_params)
@user.update_attributes(user_params)
render_wizard @user
end
private
def user_params
params.require(:user)
.permit(:gender, :first_name, :last_name, :email, :password, :password_confirmation, :phone,
:clinic_logo,
:practitioner_image,
:public_health_insurance,
clinic_images: [],
profession_ids: [],
speciality_ids: [],
services_attributes: [:id, :description, :name, :duration, :price, :_destroy],
educations_attributes: [:id, :name, :place, :year, :_destroy],
membership_ids: [],
awards_attributes: [:id, :name, :year, :_destroy],
clinics_attributes: [:id, :clinic_logo, :clinic_name, :clinic_address, :clinic_zip_code, :clinic_municipality, :clinic_about, :clinic_mail, :clinic_phone, :clinic_website, :clinic_city, :_destroy],
practitioners_attributes: [:id, :practitioner_first_name, :practitioner_last_name, :practitioner_description, :practitioner_mail, :practitioner_phone, :practitioner_website, :_destroy])
end
end
ApplicationController.rb
class ApplicationController < ActionController::Base
protect_from_forgery with: :exception
before_action :authenticate_user!, :configure_permitted_parameters, if: :devise_controller?
protected
def configure_permitted_parameters
devise_parameter_sanitizer.permit(:sign_up, keys:
[:gender, :first_name, :last_name, :email, :password, :password_confirmation, :phone,
:clinic_logo,
:practitioner_image,
:public_health_insurance,
clinic_images: [],
profession_ids: [],
speciality_ids: [],
services_attributes: [:id, :description, :name, :duration, :price, :_destroy],
educations_attributes: [:id, :name, :place, :year, :_destroy],
membership_ids: [],
awards_attributes: [:id, :name, :year, :_destroy],
clinics_attributes: [:id, :clinic_logo, :clinic_name, :clinic_address, :clinic_zip_code, :clinic_municipality, :clinic_about, :clinic_mail, :clinic_phone, :clinic_website, :clinic_city, :_destroy],
practitioners_attributes: [:id, :practitioner_first_name, :practitioner_last_name, :practitioner_description, :practitioner_mail, :practitioner_phone, :practitioner_website, :_destroy]])
devise_parameter_sanitizer.permit(:account_update, keys:
[:gender, :first_name, :last_name, :email, :password, :password_confirmation, :phone,
:clinic_logo,
:practitioner_image,
:public_health_insurance,
clinic_images: [],
profession_ids: [],
speciality_ids: [],
services_attributes: [:id, :description, :name, :duration, :price, :_destroy],
educations_attributes: [:id, :name, :place, :year, :_destroy],
membership_ids: [],
awards_attributes: [:id, :name, :year, :_destroy],
clinics_attributes: [:id, :clinic_logo, :clinic_name, :clinic_address, :clinic_zip_code, :clinic_municipality, :clinic_about, :clinic_mail, :clinic_phone, :clinic_website, :clinic_city, :_destroy],
practitioners_attributes: [:id, :practitioner_first_name, :practitioner_last_name, :practitioner_description, :practitioner_mail, :practitioner_phone, :practitioner_website, :_destroy]])
end
def after_sign_in_path_for(resource)
rails_admin_path
end
end
routes.rb
Rails.application.routes.draw do
mount RailsAdmin::Engine => '/admin', as: 'rails_admin'
devise_for :users, controllers: {:registrations => "users/registrations"
}
resources :registration_steps
# For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html
root 'pages#index'
get 'about', to: 'pages#about'
get 'team', to: 'pages#team'
get 'faqs', to: 'pages#faqs'
get 'faqspractitioners', to: 'pages#faqspractitioners'
get 'faqsusers', to: 'pages#faqsusers'
get 'login', to: 'pages#login'
get 'signup', to: 'pages#signup'
get 'search', to: 'pages#search'
get "userprofiles/user_info" => "userprofiles#user_info", as: "user_info"
get "userprofiles/clinic_info" => "userprofiles#clinic_info", as: "clinic_info"
get "userprofiles/practitioner_info" => "userprofiles#practitioner_info", as: "practitioner_info"
patch "userprofiles/user_info" => "userprofiles#update"
patch "userprofiles/clinic_info" => "userprofiles#update"
patch "userprofiles/practitioner_info" => "userprofiles#update"
devise_scope :user do
scope module: :users do
resources :registrations, only: [] do
member do
delete :delete_image_attachment
end
end
end
end
end
看到这个:
Unpermitted parameter: :practitioners
...在您的服务器日志中?
你有 Parameters
个看起来像这样的:
{
"user"=>{
"practitioners"=>{
"practitioner_image"=> #<ActionDispatch::Http::UploadedFile:0x00007f811c002dd8 ...>,
"practitioner_first_name"=> "Kasper",
"practitioner_last_name"=> "Valentin",
"gender"=> "Mand",
"practitioner_description"=> "asasdas",
"public_health_insurance" =>"1",
"practitioner_mail" =>"kvnirvana@yahoo.dk",
"practitioner_phone" =>"24210886",
"practitioner_website" =>"www.yahoo.dk"
}
},
"commit"=>"Gem",
"id"=>"practitioners_general"
}
在你的 user_params
中,你有这个:
def user_params
params.require(:user)
.permit(
...,
practitioners_attributes: [
:id,
:practitioner_first_name,
:practitioner_last_name,
:practitioner_description,
:practitioner_mail,
:practitioner_phone,
:practitioner_website,
:_destroy
]
)
end
看到了吗?您允许 practitioners_attributes
,但您的 Parameters
有 practitioners
。由于您不允许 practitioners
,它被拒绝为 Unpermitted parameter
,这正是您的日志文件告诉您的。
如果你想允许practitioner_attributes
,那么做一些更像:
<%= f.simple_fields_for(:practitioner_attributes) do |p| %>
<%= render 'practitioners/practitioners_fields', :f => p %>
<% end %>
如果您想在 Parameters
中保留 practitioners
,则可以执行以下操作:
def user_params
params.require(:user)
.permit(
...,
practitioners: [
:id,
:practitioner_first_name,
:practitioner_last_name,
:practitioner_description,
:practitioner_mail,
:practitioner_phone,
:practitioner_website,
:_destroy
]
)
end
重点是,您 Parameters
中的内容必须与您的 permit
语句中的内容相匹配。现在,它们不匹配,所以 practitioners
是一个不允许的参数。
改变
user.rb
class User < ApplicationRecord
accepts_nested_attributes_for :practitioners, reject_if: :all_blank, allow_destroy: true
has_many :clinics, dependent: :destroy
accepts_nested_attributes_for :clinics, reject_if: :all_blank, allow_destroy: true
end
clinic.rb
class Clinic < ApplicationRecord
belongs_to :user
has_many :practitioners
end
practitioner.rb
class Practitioner < ApplicationRecord
belongs_to: clinic
end
到
user.rb
class User < ApplicationRecord
has_many :clinics, dependent: :destroy
accepts_nested_attributes_for :clinics, reject_if: :all_blank, allow_destroy: true
end
clinic.rb
class Clinic < ApplicationRecord
belongs_to :user
has_many :practitioners
accepts_nested_attributes_for :practitioners, reject_if: :all_blank, allow_destroy: true
end
practitioner.rb
class Practitioner < ApplicationRecord
belongs_to: clinic
end
原因是您对当前模型中 has_many
的模型使用 accepts_nested_attributes_for
。
所以用户应该接受 clinics
的参数,clinics
应该接受 practitioners
的参数。
更新
你不应该使用这个
<div class="content">
<div class="content practitioner">
<h2 class="page-title">Generel information</h2>
<%= simple_form_for @user, url: wizard_path, method: :put do |f| %>
<%= f.simple_fields_for(:clinics) do |p| %>
<%= render 'clinics/clinics_fields', :f => p %>
<% end %>
</div>
<div class="submit-container">
<%= f.submit "Gem", :class => 'btn blue' %>
</div>
<% end %>
</div>
应该是
practitioners_general.html.rb
<div class="content">
<div class="content practitioner">
<h2 class="page-title">Generel information</h2>
<%= simple_form_for @user, url: wizard_path, method: :put do |f| %>
<%= f.simple_fields_for(:clinics) do |p| %>
<%= render 'clinics/clinics_fields', :f => p %>
<% end %>
<div class="submit-container">
<%= f.submit "Gem", :class => 'btn blue' %>
</div>
<% end %>
</div>
</div>
_clinics_fields.html.rb
<%= f.simple_fields_for(:practitioners) do |p| %>
<%= render 'practitioners/practitioners_fields', :f => p %>
<% end %>
_practitioners_fields.html.rb
<div class="nested-fields">
<div class="basic-section">
...
...
...
</div>
</div>
您需要更好地理解嵌套参数如何工作的概念
def user_params
params.require(:user)
.permit(
...user attributes related params
clinics_attributes: [
...clinics attributes related params
practitioners_attributes: [
...practitioner attributes related params
]
])
end
clinics_attributes
应该是 user_params
的一部分,因为 clinic
属于用户。同样 practitioners_attributes
将成为 clinic_params
的一部分
我通过更改
中的参数来修复它
clinics_attributes: [:id, :clinic_logo, :clinic_name, :clinic_address, :clinic_zip_code, :clinic_municipality, :clinic_about, :clinic_mail, :clinic_phone, :clinic_website, :clinic_city, :_destroy],
practitioners_attributes: [:id, :practitioner_first_name, :practitioner_last_name, :practitioner_description, :practitioner_mail, :practitioner_phone, :practitioner_website, :_destroy])
end
至
clinics_attributes: [:id, :clinic_logo, :clinic_name, :clinic_address, :clinic_zip_code, :clinic_municipality, :clinic_about, :clinic_mail, :clinic_phone, :clinic_website, :clinic_city, :_destroy,
practitioners_attributes: [:id, :practitioner_first_name, :practitioner_last_name, :practitioner_description, :practitioner_mail, :practitioner_phone, :practitioner_website, :_destroy]])
end
我有这个设置,但是当我试图拯救一个从业者时,注释被保存到数据库中。 table 是用户、诊所和从业者。用户应该能够创建多个诊所,每个诊所应该能够向特定诊所添加多个从业者。
我从日志中得到这个错误
Started PUT "/registration_steps/practitioners_general" for ::1 at 2020-03-01 11:59:29 +0100
Processing by RegistrationStepsController#update as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"KGwLxzNk96QEiY8Enun4cK3Gd3ec0GFsJxFxIq75MDQEGVcpapxTfh7aHR6slMojd3+hQg4MevmPDewRq7vGiA==", "user"=>{"clinics_attributes"=>{"0"=>{"practitioners_attributes"=>{"1583060279301"=>{"practitioner_first_name"=>"sdsad", "practitioner_last_name"=>"sdsadsa", "practitioner_description"=>"sadasda", "practitioner_mail"=>"kvnirvana@yahoo.dk", "practitioner_phone"=>"24210886", "practitioner_website"=>""}}, "id"=>"7"}}}, "commit"=>"Gem", "id"=>"practitioners_general"}
User Load (1.9ms) SELECT `users`.* FROM `users` WHERE `users`.`id` = 95 ORDER BY `users`.`id` ASC LIMIT 1
↳ app/controllers/registration_steps_controller.rb:17
Unpermitted parameter: :practitioners_attributes
(0.2ms) BEGIN
↳ app/controllers/registration_steps_controller.rb:19
Clinic Load (0.5ms) SELECT `clinics`.* FROM `clinics` WHERE `clinics`.`user_id` = 95 AND `clinics`.`id` = 7
↳ app/controllers/registration_steps_controller.rb:19
(1.4ms) COMMIT
↳ app/controllers/registration_steps_controller.rb:19
(0.9ms) BEGIN
↳ app/controllers/registration_steps_controller.rb:20
(0.2ms) COMMIT
↳ app/controllers/registration_steps_controller.rb:20
Redirected to http://localhost:3000/registration_steps/practitioners_professions
Completed 302 Found in 18ms (ActiveRecord: 5.1ms)
Started GET "/registration_steps/practitioners_professions" for ::1 at 2020-03-01 11:59:29 +0100
Processing by RegistrationStepsController#show as HTML
Parameters: {"id"=>"practitioners_professions"}
User Load (0.4ms) SELECT `users`.* FROM `users` WHERE `users`.`id` = 95 ORDER BY `users`.`id` ASC LIMIT 1
↳ app/controllers/registration_steps_controller.rb:12
Rendering registration_steps/practitioners_professions.html.erb within layouts/application
Profession Load (0.5ms) SELECT `professions`.* FROM `professions` INNER JOIN `user_professions` ON `professions`.`id` = `user_professions`.`profession_id` WHERE `user_professions`.`user_id` = 95
↳ app/views/registration_steps/practitioners_professions.html.erb:47
Profession Load (0.4ms) SELECT `professions`.* FROM `professions`
↳ app/views/registration_steps/practitioners_professions.html.erb:47
Speciality Load (0.5ms) SELECT `specialities`.* FROM `specialities` INNER JOIN `user_specialities` ON `specialities`.`id` = `user_specialities`.`speciality_id` WHERE `user_specialities`.`user_id` = 95
↳ app/views/registration_steps/practitioners_professions.html.erb:62
Speciality Load (0.3ms) SELECT `specialities`.* FROM `specialities`
↳ app/views/registration_steps/practitioners_professions.html.erb:62
Service Load (0.3ms) SELECT `services`.* FROM `services` WHERE `services`.`user_id` = 95
↳ app/views/registration_steps/practitioners_professions.html.erb:81
Rendered services/_services_fields.html.erb (7.5ms)
Rendered services/_services_fields.html.erb (6.4ms)
Rendered registration_steps/practitioners_professions.html.erb within layouts/application (34.6ms)
Rendered layouts/_header.html.erb (4.1ms)
Rendered layouts/_footer.html.erb (0.7ms)
Completed 200 OK in 92ms (Views: 88.0ms | ActiveRecord: 2.4ms)
到目前为止,我就是这样尝试让它工作的:
用户有很多诊所
诊所属于用户
诊所有很多从业者
从业者属于诊所
我添加了一个外国用户密钥来连接诊所 table 与用户 table
我已经添加了一个外国诊所密钥来连接从业者 table 和诊所 table
user.rb
class User < ApplicationRecord
has_many :clinics, dependent: :destroy
accepts_nested_attributes_for :clinics, reject_if: :all_blank, allow_destroy: true
end
clinic.rb
class Clinic < ApplicationRecord
belongs_to :user
has_many :practitioners
accepts_nested_attributes_for :practitioners, reject_if: :all_blank, allow_destroy: true
end
practitioner.rb
class Practitioner < ApplicationRecord
belongs_to: clinic
end
为从业者添加诊所外键
class AddClinicReferenceToPratitioners < ActiveRecord::Migration[5.2]
def change
add_reference :practitioners, :clinic, foreign_key: true
end
end
将用户外键添加到诊所
class AddUserReferenceToClinics < ActiveRecord::Migration[5.2]
def change
add_reference :clinics, :user, foreign_key: true
end
end
practitioners_general.html.rb
<div class="content">
<div class="content practitioner">
<h2 class="page-title">Generel information</h2>
<%= simple_form_for @user, url: wizard_path, method: :put do |f| %>
<%= f.simple_fields_for(:clinics) do |p| %>
<%= render 'clinics/clinics_fields', :f => p %>
<% end %>
<div class="submit-container">
<%= f.submit "Gem", :class => 'btn blue' %>
</div>
<% end %>
</div>
</div>
clinics/_clinics_fields.html.erb
<%= f.simple_fields_for(:practitioners) do |p| %>
<%= render 'practitioners/practitioners_fields', :f => p %>
<% end %>
<div class="links">
<%= link_to_add_association 'Add Practitioner', f, :practitioners, :partial => 'practitioners/practitioners_fields' %>
</div>
practitioners/practitioners_fields.html.erb
<div class="nested-fields">
<div class="basic-section">
<div class="info-group">
<div class="field-group">
<div class="field text-field">
<%= f.input_field :practitioner_first_name, required: true, autofocus: true, autocomplete: "Fornavn", placeholder: "Fornavn" %>
</div>
<div class="field text-field">
<%= f.input_field :practitioner_last_name, required: true, autofocus: true, autocomplete: "Efternavn", placeholder: "Efternavn" %>
</div>
</div>
</div>
</div>
<div class="about-section">
<div class="field text-field">
<%= f.input_field :practitioner_description, :as => :text, :input_html => { 'rows' => 5}, autofocus: true, autocomplete: "Beskrivelse af behandler", placeholder: "Beskrivelse af behandler" %>
</div>
</div>
<div class="field-group contact-section">
<div class="field text-field">
<%= f.input_field :practitioner_mail, input_html: { autocomplete: 'email' }, autofocus: true, placeholder: "E-mail" %>
</div>
<div class="field text-field">
<%= f.input_field :practitioner_phone, autofocus: true, autocomplete: "Tlf. nr.", placeholder: "Tlf. nr." %>
</div>
<div class="field text-field">
<%= f.input_field :practitioner_website, required: false, autofocus: true, autocomplete: "Hjemmeside", placeholder: "Hjemmeside" %>
</div>
</div>
</div>
registration_steps_controller.rb
class RegistrationStepsController < ApplicationController
include Wicked::Wizard
steps :company_general, :company_images, :practitioners_general, :practitioners_professions, :practitioners_educations
def create
@practitioner = Practitioner.new(params[:practitioners])
@practitioner.save
end
def show
@user = current_user
render_wizard
end
def update
@user = current_user
# Change @user.attributes(user_params) by @user.update_attributes(user_params)
@user.update_attributes(user_params)
render_wizard @user
end
private
def user_params
params.require(:user)
.permit(:gender, :first_name, :last_name, :email, :password, :password_confirmation, :phone,
:clinic_logo,
:practitioner_image,
:public_health_insurance,
clinic_images: [],
profession_ids: [],
speciality_ids: [],
services_attributes: [:id, :description, :name, :duration, :price, :_destroy],
educations_attributes: [:id, :name, :place, :year, :_destroy],
membership_ids: [],
awards_attributes: [:id, :name, :year, :_destroy],
clinics_attributes: [:id, :clinic_logo, :clinic_name, :clinic_address, :clinic_zip_code, :clinic_municipality, :clinic_about, :clinic_mail, :clinic_phone, :clinic_website, :clinic_city, :_destroy],
practitioners_attributes: [:id, :practitioner_first_name, :practitioner_last_name, :practitioner_description, :practitioner_mail, :practitioner_phone, :practitioner_website, :_destroy])
end
end
ApplicationController.rb
class ApplicationController < ActionController::Base
protect_from_forgery with: :exception
before_action :authenticate_user!, :configure_permitted_parameters, if: :devise_controller?
protected
def configure_permitted_parameters
devise_parameter_sanitizer.permit(:sign_up, keys:
[:gender, :first_name, :last_name, :email, :password, :password_confirmation, :phone,
:clinic_logo,
:practitioner_image,
:public_health_insurance,
clinic_images: [],
profession_ids: [],
speciality_ids: [],
services_attributes: [:id, :description, :name, :duration, :price, :_destroy],
educations_attributes: [:id, :name, :place, :year, :_destroy],
membership_ids: [],
awards_attributes: [:id, :name, :year, :_destroy],
clinics_attributes: [:id, :clinic_logo, :clinic_name, :clinic_address, :clinic_zip_code, :clinic_municipality, :clinic_about, :clinic_mail, :clinic_phone, :clinic_website, :clinic_city, :_destroy],
practitioners_attributes: [:id, :practitioner_first_name, :practitioner_last_name, :practitioner_description, :practitioner_mail, :practitioner_phone, :practitioner_website, :_destroy]])
devise_parameter_sanitizer.permit(:account_update, keys:
[:gender, :first_name, :last_name, :email, :password, :password_confirmation, :phone,
:clinic_logo,
:practitioner_image,
:public_health_insurance,
clinic_images: [],
profession_ids: [],
speciality_ids: [],
services_attributes: [:id, :description, :name, :duration, :price, :_destroy],
educations_attributes: [:id, :name, :place, :year, :_destroy],
membership_ids: [],
awards_attributes: [:id, :name, :year, :_destroy],
clinics_attributes: [:id, :clinic_logo, :clinic_name, :clinic_address, :clinic_zip_code, :clinic_municipality, :clinic_about, :clinic_mail, :clinic_phone, :clinic_website, :clinic_city, :_destroy],
practitioners_attributes: [:id, :practitioner_first_name, :practitioner_last_name, :practitioner_description, :practitioner_mail, :practitioner_phone, :practitioner_website, :_destroy]])
end
def after_sign_in_path_for(resource)
rails_admin_path
end
end
routes.rb
Rails.application.routes.draw do
mount RailsAdmin::Engine => '/admin', as: 'rails_admin'
devise_for :users, controllers: {:registrations => "users/registrations"
}
resources :registration_steps
# For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html
root 'pages#index'
get 'about', to: 'pages#about'
get 'team', to: 'pages#team'
get 'faqs', to: 'pages#faqs'
get 'faqspractitioners', to: 'pages#faqspractitioners'
get 'faqsusers', to: 'pages#faqsusers'
get 'login', to: 'pages#login'
get 'signup', to: 'pages#signup'
get 'search', to: 'pages#search'
get "userprofiles/user_info" => "userprofiles#user_info", as: "user_info"
get "userprofiles/clinic_info" => "userprofiles#clinic_info", as: "clinic_info"
get "userprofiles/practitioner_info" => "userprofiles#practitioner_info", as: "practitioner_info"
patch "userprofiles/user_info" => "userprofiles#update"
patch "userprofiles/clinic_info" => "userprofiles#update"
patch "userprofiles/practitioner_info" => "userprofiles#update"
devise_scope :user do
scope module: :users do
resources :registrations, only: [] do
member do
delete :delete_image_attachment
end
end
end
end
end
看到这个:
Unpermitted parameter: :practitioners
...在您的服务器日志中?
你有 Parameters
个看起来像这样的:
{
"user"=>{
"practitioners"=>{
"practitioner_image"=> #<ActionDispatch::Http::UploadedFile:0x00007f811c002dd8 ...>,
"practitioner_first_name"=> "Kasper",
"practitioner_last_name"=> "Valentin",
"gender"=> "Mand",
"practitioner_description"=> "asasdas",
"public_health_insurance" =>"1",
"practitioner_mail" =>"kvnirvana@yahoo.dk",
"practitioner_phone" =>"24210886",
"practitioner_website" =>"www.yahoo.dk"
}
},
"commit"=>"Gem",
"id"=>"practitioners_general"
}
在你的 user_params
中,你有这个:
def user_params
params.require(:user)
.permit(
...,
practitioners_attributes: [
:id,
:practitioner_first_name,
:practitioner_last_name,
:practitioner_description,
:practitioner_mail,
:practitioner_phone,
:practitioner_website,
:_destroy
]
)
end
看到了吗?您允许 practitioners_attributes
,但您的 Parameters
有 practitioners
。由于您不允许 practitioners
,它被拒绝为 Unpermitted parameter
,这正是您的日志文件告诉您的。
如果你想允许practitioner_attributes
,那么做一些更像:
<%= f.simple_fields_for(:practitioner_attributes) do |p| %>
<%= render 'practitioners/practitioners_fields', :f => p %>
<% end %>
如果您想在 Parameters
中保留 practitioners
,则可以执行以下操作:
def user_params
params.require(:user)
.permit(
...,
practitioners: [
:id,
:practitioner_first_name,
:practitioner_last_name,
:practitioner_description,
:practitioner_mail,
:practitioner_phone,
:practitioner_website,
:_destroy
]
)
end
重点是,您 Parameters
中的内容必须与您的 permit
语句中的内容相匹配。现在,它们不匹配,所以 practitioners
是一个不允许的参数。
改变
user.rb
class User < ApplicationRecord
accepts_nested_attributes_for :practitioners, reject_if: :all_blank, allow_destroy: true
has_many :clinics, dependent: :destroy
accepts_nested_attributes_for :clinics, reject_if: :all_blank, allow_destroy: true
end
clinic.rb
class Clinic < ApplicationRecord
belongs_to :user
has_many :practitioners
end
practitioner.rb
class Practitioner < ApplicationRecord
belongs_to: clinic
end
到
user.rb
class User < ApplicationRecord
has_many :clinics, dependent: :destroy
accepts_nested_attributes_for :clinics, reject_if: :all_blank, allow_destroy: true
end
clinic.rb
class Clinic < ApplicationRecord
belongs_to :user
has_many :practitioners
accepts_nested_attributes_for :practitioners, reject_if: :all_blank, allow_destroy: true
end
practitioner.rb
class Practitioner < ApplicationRecord
belongs_to: clinic
end
原因是您对当前模型中 has_many
的模型使用 accepts_nested_attributes_for
。
所以用户应该接受 clinics
的参数,clinics
应该接受 practitioners
的参数。
更新
你不应该使用这个
<div class="content">
<div class="content practitioner">
<h2 class="page-title">Generel information</h2>
<%= simple_form_for @user, url: wizard_path, method: :put do |f| %>
<%= f.simple_fields_for(:clinics) do |p| %>
<%= render 'clinics/clinics_fields', :f => p %>
<% end %>
</div>
<div class="submit-container">
<%= f.submit "Gem", :class => 'btn blue' %>
</div>
<% end %>
</div>
应该是
practitioners_general.html.rb
<div class="content">
<div class="content practitioner">
<h2 class="page-title">Generel information</h2>
<%= simple_form_for @user, url: wizard_path, method: :put do |f| %>
<%= f.simple_fields_for(:clinics) do |p| %>
<%= render 'clinics/clinics_fields', :f => p %>
<% end %>
<div class="submit-container">
<%= f.submit "Gem", :class => 'btn blue' %>
</div>
<% end %>
</div>
</div>
_clinics_fields.html.rb
<%= f.simple_fields_for(:practitioners) do |p| %>
<%= render 'practitioners/practitioners_fields', :f => p %>
<% end %>
_practitioners_fields.html.rb
<div class="nested-fields">
<div class="basic-section">
...
...
...
</div>
</div>
您需要更好地理解嵌套参数如何工作的概念
def user_params
params.require(:user)
.permit(
...user attributes related params
clinics_attributes: [
...clinics attributes related params
practitioners_attributes: [
...practitioner attributes related params
]
])
end
clinics_attributes
应该是 user_params
的一部分,因为 clinic
属于用户。同样 practitioners_attributes
将成为 clinic_params
我通过更改
中的参数来修复它 clinics_attributes: [:id, :clinic_logo, :clinic_name, :clinic_address, :clinic_zip_code, :clinic_municipality, :clinic_about, :clinic_mail, :clinic_phone, :clinic_website, :clinic_city, :_destroy],
practitioners_attributes: [:id, :practitioner_first_name, :practitioner_last_name, :practitioner_description, :practitioner_mail, :practitioner_phone, :practitioner_website, :_destroy])
end
至
clinics_attributes: [:id, :clinic_logo, :clinic_name, :clinic_address, :clinic_zip_code, :clinic_municipality, :clinic_about, :clinic_mail, :clinic_phone, :clinic_website, :clinic_city, :_destroy,
practitioners_attributes: [:id, :practitioner_first_name, :practitioner_last_name, :practitioner_description, :practitioner_mail, :practitioner_phone, :practitioner_website, :_destroy]])
end