HABTM 与 rails API 的关系无效
HABTM relationship with rails API does not work
我是 Rails Ruby 的新人。我正在使用 Rails 5.1、活动记录序列化程序、门卫和设计 gem.
制作 Rails API
我有一个 Order
table,它有很多产品。订单和产品是多对多的关系。
订购型号:
class Order < ApplicationRecord
validates_presence_of :brute, :net
has_and_belongs_to_many :products
end
产品型号:
class Product < ApplicationRecord
belongs_to :category
validates_presence_of :name, :price
validates_uniqueness_of :name
has_and_belongs_to_many :orders
end
我有一个名为 orders_products
的连接 table。
订单序列化程序:
class OrderSerializer < ActiveModel::Serializer
attributes :id, :discount, :brute, :net, :payed, :payed_at, :products
def products
object.products.map do |product|
ProductSerializer.new(product, scope: scope, root: false, event: object)
end
end
end
产品序列化程序:
class ProductSerializer < ActiveModel::Serializer
attributes :id, :name, :price, :description
has_one :category
end
订单控制器:
module Api
class OrdersController < ApiController
before_action :set_order, only: [:show, :update, :destroy]
# GET /api/orders
def index
@orders = Order.all
render json: @orders
end
# GET /api/orders/1
def show
render json: @order
end
# POST /api/orders
def create
@order = Order.new(order_params)
if @order.save
render json: @order, status: :created, location: api_order_url(@order)
else
render json: @order.errors, status: :unprocessable_entity
end
end
# PATCH/PUT /api/orders/1
def update
if @order.present?
if @order.update(order_params)
render json: @order
else
render json: @order.errors, status: :unprocessable_entity
end
end
end
# DELETE /api/orders/1
def destroy
@order.destroy if @order.present?
end
private
# Use callbacks to share common setup or constraints between actions.
def set_order
@order = Order.find(params[:id])
rescue ActiveRecord::RecordNotFound
Rails.logger.error{ 'Order record is not found' }
nil
end
# Only allow a trusted parameter "white list" through.
def order_params
params.require(:order).permit(:discount, :brute, :net, :payed, :payed_at, product_ids: [])
end
end
end
当我post从API生成器应用Postman/Insomnia订购json数据时,订单被保存在订单table中,但没有保存数据在 orders_products
加入 table.
我的请求(POST http://localhost:3000/api/orders) 订单json:
{
"discount": 110,
"brute": 100,
"net": 200,
"payed": null,
"payed_at": null,
"product_ids": [3]
}
我试图找到解决方案,但我失败了。
据我所知,Rails 不会在给定 ID 列表时自动处理连接记录的创建。因此,当您调用 @order = Order.new(order_params)
并期望它知道如何处理 product_ids: [3]
时,它只是忽略了它。
如果您使用以下内容修改 create
端点,您应该会看到正在创建的加入记录。
# POST /api/orders
def create
@order = Order.new(order_params)
if @order.save
# Find products
@products = Product.where(id: order_params[:product_ids])
# Create join table records
@products.each { |product| product.orders << order }
render json: @order, status: :created, location: api_order_url(@order)
else
render json: @order.errors, status: :unprocessable_entity
end
end
这只是一种不进行任何错误检查的可能解决方案。根据您的应用程序所需的安全性和稳健性,您可能需要创建一个服务来包装它并处理在创建订单和关联记录之前验证是否找到了产品。
编辑:OrderSerializer
验证连接 table 记录是否正确创建后。检查你的序列化器是否正常工作,它们有很好的文档。我相信你可以用这个替换 OrderSerializer
中当前的 products
方法:
class OrderSerializer < ActiveModel::Serializer
attributes :id, :discount, :brute, :net, :payed, :payed_at, :products
def products
object.products.map do |product|
ProductSerializer.new(product).serializable_hash
end
end
end
我终于解决了你的 problem.Just 在你的模型中添加一个属性。
订购型号:
class Order < ApplicationRecord
attribute :product_ids
validates_presence_of :brute, :net
has_and_belongs_to_many :products
end
订单序列化程序:
class OrderSerializer < ActiveModel::Serializer
attributes :id, :discount, :brute, :net, :payed, :payed_at
has_many :products
end
并按照您的顺序创建方法 api:
# POST /api/orders
def create
@order = Order.new(order_params)
if @order.save
# Find products
@products = Product.where(id: order_params[:product_ids])
# Create join table records
@products.each { |product| product.orders << @order }
render json: @order, status: :created, location: api_order_url(@order)
else
render json: @order.errors, status: :unprocessable_entity
end
end
我已经在本地测试过了,可以用!快乐编程:)
我是 Rails Ruby 的新人。我正在使用 Rails 5.1、活动记录序列化程序、门卫和设计 gem.
制作 Rails API我有一个 Order
table,它有很多产品。订单和产品是多对多的关系。
订购型号:
class Order < ApplicationRecord
validates_presence_of :brute, :net
has_and_belongs_to_many :products
end
产品型号:
class Product < ApplicationRecord
belongs_to :category
validates_presence_of :name, :price
validates_uniqueness_of :name
has_and_belongs_to_many :orders
end
我有一个名为 orders_products
的连接 table。
订单序列化程序:
class OrderSerializer < ActiveModel::Serializer
attributes :id, :discount, :brute, :net, :payed, :payed_at, :products
def products
object.products.map do |product|
ProductSerializer.new(product, scope: scope, root: false, event: object)
end
end
end
产品序列化程序:
class ProductSerializer < ActiveModel::Serializer
attributes :id, :name, :price, :description
has_one :category
end
订单控制器:
module Api
class OrdersController < ApiController
before_action :set_order, only: [:show, :update, :destroy]
# GET /api/orders
def index
@orders = Order.all
render json: @orders
end
# GET /api/orders/1
def show
render json: @order
end
# POST /api/orders
def create
@order = Order.new(order_params)
if @order.save
render json: @order, status: :created, location: api_order_url(@order)
else
render json: @order.errors, status: :unprocessable_entity
end
end
# PATCH/PUT /api/orders/1
def update
if @order.present?
if @order.update(order_params)
render json: @order
else
render json: @order.errors, status: :unprocessable_entity
end
end
end
# DELETE /api/orders/1
def destroy
@order.destroy if @order.present?
end
private
# Use callbacks to share common setup or constraints between actions.
def set_order
@order = Order.find(params[:id])
rescue ActiveRecord::RecordNotFound
Rails.logger.error{ 'Order record is not found' }
nil
end
# Only allow a trusted parameter "white list" through.
def order_params
params.require(:order).permit(:discount, :brute, :net, :payed, :payed_at, product_ids: [])
end
end
end
当我post从API生成器应用Postman/Insomnia订购json数据时,订单被保存在订单table中,但没有保存数据在 orders_products
加入 table.
我的请求(POST http://localhost:3000/api/orders) 订单json:
{
"discount": 110,
"brute": 100,
"net": 200,
"payed": null,
"payed_at": null,
"product_ids": [3]
}
我试图找到解决方案,但我失败了。
据我所知,Rails 不会在给定 ID 列表时自动处理连接记录的创建。因此,当您调用 @order = Order.new(order_params)
并期望它知道如何处理 product_ids: [3]
时,它只是忽略了它。
如果您使用以下内容修改 create
端点,您应该会看到正在创建的加入记录。
# POST /api/orders
def create
@order = Order.new(order_params)
if @order.save
# Find products
@products = Product.where(id: order_params[:product_ids])
# Create join table records
@products.each { |product| product.orders << order }
render json: @order, status: :created, location: api_order_url(@order)
else
render json: @order.errors, status: :unprocessable_entity
end
end
这只是一种不进行任何错误检查的可能解决方案。根据您的应用程序所需的安全性和稳健性,您可能需要创建一个服务来包装它并处理在创建订单和关联记录之前验证是否找到了产品。
编辑:OrderSerializer
验证连接 table 记录是否正确创建后。检查你的序列化器是否正常工作,它们有很好的文档。我相信你可以用这个替换 OrderSerializer
中当前的 products
方法:
class OrderSerializer < ActiveModel::Serializer
attributes :id, :discount, :brute, :net, :payed, :payed_at, :products
def products
object.products.map do |product|
ProductSerializer.new(product).serializable_hash
end
end
end
我终于解决了你的 problem.Just 在你的模型中添加一个属性。
订购型号:
class Order < ApplicationRecord
attribute :product_ids
validates_presence_of :brute, :net
has_and_belongs_to_many :products
end
订单序列化程序:
class OrderSerializer < ActiveModel::Serializer
attributes :id, :discount, :brute, :net, :payed, :payed_at
has_many :products
end
并按照您的顺序创建方法 api:
# POST /api/orders
def create
@order = Order.new(order_params)
if @order.save
# Find products
@products = Product.where(id: order_params[:product_ids])
# Create join table records
@products.each { |product| product.orders << @order }
render json: @order, status: :created, location: api_order_url(@order)
else
render json: @order.errors, status: :unprocessable_entity
end
end
我已经在本地测试过了,可以用!快乐编程:)