是否有建议的方法在 RoR 中创建嵌套多对多实体,以避免嵌套资源的 JSON 字段中的 *_attributes?
我成功地通过使用 JSON 和下面的项目的 accepts_nested_attributes_for
创建了嵌套的多对多实体。
我的问题是 - 是否有一种建议的方法可以实现相同的效果,无需添加 _attributes
即可在 RoR 上创建 emotion
对象数组服务器?我所说的建议要么是框架本身建议的东西,要么是尽可能干净的东西。
JSON 发布到 http://localhost:3000/periods:
{
"period": {
"date": "2022-03-17T03:00:52.820Z",
"period": "morning",
"emotions_attributes": [
{
"name": "ok"
},
{
"name": "fine"
}
]
}
}
用于创建后续文件的 railsgenerate
命令:
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
periods.rb:
class Period < ApplicationRecord
has_many :entries
has_many :emotions, through: :entries
accepts_nested_attributes_for :emotions
end
emotion.rb
class Emotion < ApplicationRecord
has_many :entries
has_many :periods, through: :entries
end
entry.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
routes.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"
}
]
}
}
I've managed to get nested many-to-many entities created through the use of accepts_nested_attributes_for
for the JSON and the project below.
My question is - is there a suggested way to achieve the same thing where I don't have to add _attributes
to be able to create the array of emotion
objects on the RoR server? What I mean by suggested is either something the framework itself suggests or otherwise something as clean as possible.
JSON getting posted to http://localhost:3000/periods:
{
"period": {
"date": "2022-03-17T03:00:52.820Z",
"period": "morning",
"emotions_attributes": [
{
"name": "ok"
},
{
"name": "fine"
}
]
}
}
rails generate
commands used to create subsequent files:
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
periods.rb:
class Period < ApplicationRecord
has_many :entries
has_many :emotions, through: :entries
accepts_nested_attributes_for :emotions
end
emotion.rb
class Emotion < ApplicationRecord
has_many :entries
has_many :periods, through: :entries
end
entry.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
routes.rb
Rails.application.routes.draw do
resources :entries
resources :periods
What I'd like to be able to post is this:
{
"period": {
"date": "2022-03-17T03:00:52.820Z",
"period": "morning",
"emotions": [
{
"name": "ok"
},
{
"name": "fine"
}
]
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您不会找到更干净的方法来实现该目标,因为“emotions_attributes”由框架“开箱即用”处理。
或者,您可以创建一个服务对象以进行更多自定义周期创建(fe app/services/periods/create.rb)并从控制器调用它。通过这种方式,您可以自定义默认约定并将逻辑保留在一个位置。
但恕我直言,只要您刚刚开始使用 Rails 之旅,您就应该保留默认约定,并且主要关心的是“情感看起来比情感属性更好”。
you won't find the cleaner way to achieve that cause "emotions_attributes" are handled "out of the box" by the framework.
alternatively you can create an service object for more custom period creation (fe app/services/periods/create.rb) and call it from controller. This way you can customize default convention and keep the logic in one place.
But imho you should stay with the default convention as long as you are just starting your journey with rails and the main concern is that "emotions looks better than emotions_attributes".
好吧,你可以像这样允许你的参数:
然后你在 #create 中可以做的第一件事是:
这是实现你的目标的一种方法,但是回答你的问题,没有建议的方法可以做到这一点。
Well, you could permit your params like this:
And then the first thing you could do in #create is:
This is a way to achieve your goal, but answering your question, there is no suggested way of doing that.