提问人:foamroll 提问时间:3/17/2022 最后编辑:foamroll 更新时间:3/17/2022 访问量:69
有没有一种建议的方法可以在 RoR 中创建嵌套的多对多实体,以避免嵌套资源的 JSON 字段中的 *_attributes?
Is there a suggested way to create nested many-to-many entities in RoR that avoids *_attributes in the JSON field for the nested resource?
问:
我已经设法通过使用 for JSON 和下面的项目创建了嵌套的多对多实体。accepts_nested_attributes_for
我的问题是 - 有没有一种建议的方法可以实现同样的事情,我不必添加就可以在 RoR 服务器上创建对象数组?我所说的建议要么是框架本身所建议的,要么是尽可能干净的东西。_attributes
emotion
JSON 被发布到 http://localhost:3000/periods:
{
"period": {
"date": "2022-03-17T03:00:52.820Z",
"period": "morning",
"emotions_attributes": [
{
"name": "ok"
},
{
"name": "fine"
}
]
}
}
rails generate
用于创建后续文件的命令:
rails g model Emotion name:string
rails g scaffold Period date:date period:string --skip-template-engine
rails g scaffold Entry emotion:references period:references --skip-template-engine
句点.rb:
class Period < ApplicationRecord
has_many :entries
has_many :emotions, through: :entries
accepts_nested_attributes_for :emotions
end
情感.rb
class Emotion < ApplicationRecord
has_many :entries
has_many :periods, through: :entries
end
条目.rb
class Entry < ApplicationRecord
belongs_to :emotion
belongs_to :period
end
periods_controller.rb
class PeriodsController < ApplicationController
before_action :set_period, only: %i[ show edit update destroy ]
skip_before_action :verify_authenticity_token
...
def create
@period = Period.new(period_params)
respond_to do |format|
if @period.save
format.html { redirect_to period_url(@period), notice: "Period was successfully created." }
format.json { render :show, status: :created, location: @period }
else
format.html { render :new, status: :unprocessable_entity }
format.json { render json: @period.errors, status: :unprocessable_entity }
end
end
end
...
# FYI turns out the id is key here to be able to even perform create
def period_params
params.require(:period).permit(
:date,
:period,
emotions_attributes: [:id, :name]
)
end
路由.rb
Rails.application.routes.draw do
resources :entries
resources :periods
我希望能够发布的是:
{
"period": {
"date": "2022-03-17T03:00:52.820Z",
"period": "morning",
"emotions": [
{
"name": "ok"
},
{
"name": "fine"
}
]
}
}
答:
1赞
res
3/17/2022
#1
你不会找到更简洁的方法来实现这一点,因为“emotions_attributes”是由框架“开箱即用”地处理的。
或者,您可以创建一个服务对象以创建更多自定义周期(fe app/services/periods/create.rb),并从控制器调用它。这样,您可以自定义默认约定并将逻辑保留在一个地方。
但恕我直言,只要您刚刚开始您的轨道之旅,您就应该保持默认约定,并且主要担心的是“情绪看起来比emotions_attributes好”。
评论
0赞
foamroll
3/21/2022
在 Virtus gem 的帮助下,如果 *_attributes 是不可取的,那么这样的事情将是要走的路
0赞
Ruan Lopes de Andrade
3/17/2022
#2
好吧,你可以像这样允许你的参数:
def period_params_hand
params.require(:period).permit(
:date,
:period,
emotions: [:id, :name]
)
end
然后,您可以在 #create 中做的第一件事是:
# receive the permitted params
period_params = period_params_hand
# rename the hash key
period_params[:emotions_attributes] = period_params.delete(:emotions)
这是实现目标的一种方式,但回答您的问题时,没有建议的方法。
评论
0赞
foamroll
3/21/2022
这没有用。我想它只会改变服务器端的参数,一旦它们进来了?
评论