ruby-on-rails - rails,相关字段在提交时未保存
问题描述
我正在尝试保存分配给它的受让人项目。所有字段都被保存,除了“被分配人”字段,它是一个关联字段。
# app/models/project.rb
class Project < ApplicationRecord
belongs_to :owner, class_name: 'User'
has_many :assignments, dependent: :destroy
has_many :assignees, through: :assignments, source: :user
has_and_belongs_to_many :adversaries, -> { adversaries }, class_name: 'Contact'
has_and_belongs_to_many :clients, -> { clients }, class_name: 'Contact'
end
# app/models/assignment.rb
class Assignment < ApplicationRecord
belongs_to :project
belongs_to :user
end
# app/models/user.rb
class User < ApplicationRecord
has_many :owned_projects, foreign_key: :owner_id, class_name: 'Project', dependent: :destroy
has_many :activities
has_many :deadlines
has_many :assignments, dependent: :destroy
has_many :projects, through: :assignments
end
# app/models/contact.rb
class Contact < ApplicationRecord
has_and_belongs_to_many :projects
scope :get_role, -> (str) { includes(:role).where("contact_roles.label = '#{str}'").references(:contact_roles) }
scope :clients, -> { get_role('client') }
scope :adversaries, -> { get_role('adversary') }
end
# app/controllers/projects_controller.rb
class ProjectsController < ApplicationController
def create
@project = Project.new(project_params)
respond_to do |format|
if @project.save
format.html { redirect_to @project, notice: "Project was successfully created." }
else
format.html { render :new, status: :unprocessable_entity }
end
end
end
private
def project_params
params.require(:project).permit(:label, :reference, :status, :description, :owner_id, :project_category_id, assignee: [:id])
end
end
# app/views/projects/_form.html.erb
<%= form_with(model: project, local: true, class: 'box') do |form| %>
<%= form.label :assignee_id %>
<%= form.collection_select(:assignee_id, User.all.order(role: :desc, last_name: :asc), :id, :friendly_name, { include_hidden: false }, { size: 6, required: true, multiple: true, id: :project_assignee_id }) %>
<% end %>
这是相关的终端输出:
Started POST "/en/projects" for 127.0.0.1 at 2021-06-19 15:43:53 +0200
Processing by ProjectsController#create as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"r3ayqmMUFEh93KKhmqJ1VEYeF90QxpFOZiHwgZ0WEeqZM/DEQsI9tpJP8CwFqH0xBF4TZlQ5++Q6o6wt2hRkRA==", "project"=>{"label"=>"asdasdasd", "owner_id"=>"3", "project_category_id"=>"1", "description"=>"asdasdasd", "status"=>"active", "reference"=>"asdasd", "assignee_id"=>["3", "2"]}, "commit"=>"Créer projet", "locale"=>"en"}
User Load (0.1ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT ? [["id", 4], ["LIMIT", 1]]
Unpermitted parameter: :assignee_id
(0.0ms) begin transaction
User Load (0.1ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT ? [["id", 3], ["LIMIT", 1]]
SQL (0.4ms) INSERT INTO "projects" ("label", "reference", "status", "description", "owner_id", "project_category_id", "created_at", "updated_at") VALUES (?, ?, ?, ?, ?, ?, ?, ?) [["label", "asdasdasd"], ["reference", "asdasd"], ["status", 1], ["description", "asdasdasd"], ["owner_id", 3], ["project_category_id", 1], ["created_at", "2021-06-19 13:43:53.565072"], ["updated_at", "2021-06-19 13:43:53.565072"]]
(0.3ms) commit transaction
Redirected to http://localhost:3000/en/projects/289
Completed 302 Found in 8ms (ActiveRecord: 1.2ms)
未经许可的参数也很神秘,因为我已经尝试了我在网上找到的所有变体......
关于如何进行的任何想法?甚至只是指向有关该问题的清晰教程的链接?
编辑:
同样的问题,但可能更清晰的代码:
# app/views/projects/_form.html.erb
<%= form.label :assignees %>
<%= form.collection_select(:assignees, User.lawyers.order(role: :desc, last_name: :asc), :id, :friendly_name, { include_hidden: false }, { size: 6, required: true, multiple: true, id: :project_assignees }) %>
# app/controllers/projects_controller.rb
def project_params
params.require(:project).permit(:label, :reference, :status, :description, :owner_id, :project_category_id, assignees: [:id])
end
这现在清除了未经允许的参数问题,但“受让人”字段仍未保存:
Started POST "/en/projects" for 127.0.0.1 at 2021-06-19 16:09:40 +0200
Processing by ProjectsController#create as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"XHqUoeH4o6XTOTlRPkNebIIhmJw6dgitxTnBtydUfvCvbCVNzNJx9dmMwA1UpSZn3FdVDjeJ21fNhtUP9YA89w==", "project"=>{"label"=>"aasdf", "owner_id"=>"3", "project_category_id"=>"1", "description"=>"asdasd", "status"=>"active", "reference"=>"", "assignees"=>["9"]}, "commit"=>"Créer projet", "locale"=>"en"}
User Load (0.1ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT ? [["id", 4], ["LIMIT", 1]]
(0.0ms) begin transaction
User Load (0.2ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT ? [["id", 3], ["LIMIT", 1]]
SQL (0.7ms) INSERT INTO "projects" ("label", "reference", "status", "description", "owner_id", "project_category_id", "created_at", "updated_at") VALUES (?, ?, ?, ?, ?, ?, ?, ?) [["label", "aasdf"], ["reference", ""], ["status", 1], ["description", "asdasd"], ["owner_id", 3], ["project_category_id", 1], ["created_at", "2021-06-19 14:09:40.963949"], ["updated_at", "2021-06-19 14:09:40.963949"]]
(0.3ms) commit transaction
Redirected to http://localhost:3000/en/projects/296
Completed 302 Found in 10ms (ActiveRecord: 1.4ms)
解决方案
您想使用宏生成assignee_ids=
的设置器:has_many
<%=
form.collection_select(
:assignee_ids,
User.lawyers.order(role: :desc, last_name: :asc), # query should be moved to controller
:id,
:friendly_name,
{ include_hidden: false },
{ size: 6, required: true, multiple: true, id: :project_assignees }
)
%>
def project_params
params.require(:project)
.permit(
:label, :reference, :status, :description,
:owner_id, :project_category_id,
assignee_ids: [] # permits an array of ids
)
end
请注意,此处不需要嵌套属性,这是一个非常常见的误解。如果您只想分配一个关系并隐式创建/销毁连接行,那么您只需要使用_ids
setter/getter,Rails 会为您处理它。
仅当您需要使用描述两个实体之间关系的附加属性显式创建连接行时,才需要嵌套属性。例如,如果您需要将“角色”字段添加到描述项目中受让人角色的分配中。
推荐阅读
- ruby-on-rails - 在不同的类别中显示相同的任务
- c++ - 具有默认值的 const 引用参数
- react-native - React Native:如何在覆盖视图中响应事件,然后将事件传递到下一层视图
- visual-studio-code - Visual Studio Code - 空白窗口无边框
- jestjs - 为什么我使用玩笑得到未知选项“extensionsToTreatAsEsm”
- python-sphinx - 尝试创建 DOCX 时出现 Sphinx/PlantUML 错误
- javascript - 无法更改媒体查询
- python - xgboost 给出 inf 或 nan 错误,但训练数据中没有无限值
- r - 在 R 中创建一个“生存”假人(面板数据)
- flutter - 无法从颤动的小部件地图中分配小部件