active_record-acts_as gem 多次更新 created_at
active_record-acts_as gem updating created_at multiple times
我正在创建一个 Rails 5.2 电子商务应用程序。我正在使用 active_record-acts_as gem 来模拟多 table 继承,它有一个名为 Product
的父 class 和多个子 classes (Book
、Clothing
、Electronic
...等)都充当 Product
(它们继承了 Product 的所有属性和方法)。
每个产品只能在 Category
的上下文中创建,它对应于产品的子class 名称。为了视觉效果,这是我当前的 ProductsController...
class ProductsController < ApplicationController
before_action :set_category, only: [:new, :create]
before_action :set_product_type, only: [:new, :create]
before_action :set_product, only: [:show, :edit, :destroy]
def show
authorize @product
end
def new
@product = Product.new(actable: @product_type.new)
authorize @product
end
def create
@product = @product_type.new product_params
authorize @product
@product.category = @category
@product.user = current_user
if @product.save
redirect_to product_path @product.slug
else
render :new
end
end
def edit
@product = Product.friendly.find(params[:id])
authorize @product
@category = @product.category
set_product_type
end
def update
@product = Product.friendly.find(params[:id])
authorize @product
@category = @product.category
set_product_type
if @product.update product_params
redirect_to product_path @product.slug
else
render :edit
end
end
def destroy
authorize @product
@category = @product.category
if @product.destroy
redirect_to category_path(@category)
else
redirect_to request.referrer
end
end
private
def set_category
@category = Category.friendly.find(params[:category_id])
end
def set_product
# specific comes from active_record_acts-as gem
@product = Product.friendly.find(params[:id]).specific
end
def set_product_type
@product_type = @category.name.singularize.capitalize.constantize
end
def product_params
params.require(:product).permit(:name, :description, :price_cents, :main_image, actable_attributes: (@product_type.permitted_params))
end
end
目前一切正常。但是,我不得不根据 将其添加到产品模型中,尽管我将其修改为使用 update
而不是 new
,以更正我的特定问题。
ACTABLE_TYPES = %w(Book Supply Electronic etc...)
def build_actable(params)
raise "Unknown actable_type: #{actable_type}" unless ACTABLE_TYPES.include?(actable_type)
self.actable.update(params)
end
如果不包含 build_actable
方法,则创建操作有效,但更新操作无效。当我尝试更新产品(产品的子 class)时没有 build_actable
的错误是...
Cannot build association actable. Are you trying to build a polymorphic one-to-one association?
主要问题
虽然我当前的控制器和build_actable
方法"works",但每次我更新产品属性时,它都会更新updated_at
三次...这是日志输出...
Book Load (0.7ms) SELECT "books".* FROM "books" WHERE "books"."id" = LIMIT [["id", 13], ["LIMIT", 1]]
↳ app/controllers/products_controller.rb:45
Product Update (1.0ms) UPDATE "products" SET "name" = , "updated_at" = WHERE "products"."id" = [["name", "Where Angels Fear to Tread something else "], ["updated_at", "2018-07-26 03:28:30.414635"], ["id", 13]]
↳ app/models/product.rb:22
Product Update (0.7ms) UPDATE "products" SET "updated_at" = WHERE "products"."id" = [["updated_at", "2018-07-26 03:28:30.417622"], ["id", 13]]
↳ app/models/product.rb:22
Product Update (0.5ms) UPDATE "products" SET "updated_at" = WHERE "products"."id" = [["updated_at", "2018-07-26 03:28:30.420007"], ["id", 13]]
↳ app/models/product.rb:22
(5.0ms) COMMIT
我的控制器当然应该重构...但是为什么它更新了 updated_at
3 次???
注意:我试过直接调用 build_actable 而不是在控制器中更新...但它做同样的事情。我还从 Product 的 subclasses 中删除了时间戳。
我觉得我错过了一些明显的东西....
我能够通过将 touch: false
添加到作为产品子类中的关联的行为来更正两次更新时间戳的问题...
acts_as :product, touch: false
我正在创建一个 Rails 5.2 电子商务应用程序。我正在使用 active_record-acts_as gem 来模拟多 table 继承,它有一个名为 Product
的父 class 和多个子 classes (Book
、Clothing
、Electronic
...等)都充当 Product
(它们继承了 Product 的所有属性和方法)。
每个产品只能在 Category
的上下文中创建,它对应于产品的子class 名称。为了视觉效果,这是我当前的 ProductsController...
class ProductsController < ApplicationController
before_action :set_category, only: [:new, :create]
before_action :set_product_type, only: [:new, :create]
before_action :set_product, only: [:show, :edit, :destroy]
def show
authorize @product
end
def new
@product = Product.new(actable: @product_type.new)
authorize @product
end
def create
@product = @product_type.new product_params
authorize @product
@product.category = @category
@product.user = current_user
if @product.save
redirect_to product_path @product.slug
else
render :new
end
end
def edit
@product = Product.friendly.find(params[:id])
authorize @product
@category = @product.category
set_product_type
end
def update
@product = Product.friendly.find(params[:id])
authorize @product
@category = @product.category
set_product_type
if @product.update product_params
redirect_to product_path @product.slug
else
render :edit
end
end
def destroy
authorize @product
@category = @product.category
if @product.destroy
redirect_to category_path(@category)
else
redirect_to request.referrer
end
end
private
def set_category
@category = Category.friendly.find(params[:category_id])
end
def set_product
# specific comes from active_record_acts-as gem
@product = Product.friendly.find(params[:id]).specific
end
def set_product_type
@product_type = @category.name.singularize.capitalize.constantize
end
def product_params
params.require(:product).permit(:name, :description, :price_cents, :main_image, actable_attributes: (@product_type.permitted_params))
end
end
目前一切正常。但是,我不得不根据 update
而不是 new
,以更正我的特定问题。
ACTABLE_TYPES = %w(Book Supply Electronic etc...)
def build_actable(params)
raise "Unknown actable_type: #{actable_type}" unless ACTABLE_TYPES.include?(actable_type)
self.actable.update(params)
end
如果不包含 build_actable
方法,则创建操作有效,但更新操作无效。当我尝试更新产品(产品的子 class)时没有 build_actable
的错误是...
Cannot build association actable. Are you trying to build a polymorphic one-to-one association?
主要问题
虽然我当前的控制器和build_actable
方法"works",但每次我更新产品属性时,它都会更新updated_at
三次...这是日志输出...
Book Load (0.7ms) SELECT "books".* FROM "books" WHERE "books"."id" = LIMIT [["id", 13], ["LIMIT", 1]]
↳ app/controllers/products_controller.rb:45
Product Update (1.0ms) UPDATE "products" SET "name" = , "updated_at" = WHERE "products"."id" = [["name", "Where Angels Fear to Tread something else "], ["updated_at", "2018-07-26 03:28:30.414635"], ["id", 13]]
↳ app/models/product.rb:22
Product Update (0.7ms) UPDATE "products" SET "updated_at" = WHERE "products"."id" = [["updated_at", "2018-07-26 03:28:30.417622"], ["id", 13]]
↳ app/models/product.rb:22
Product Update (0.5ms) UPDATE "products" SET "updated_at" = WHERE "products"."id" = [["updated_at", "2018-07-26 03:28:30.420007"], ["id", 13]]
↳ app/models/product.rb:22
(5.0ms) COMMIT
我的控制器当然应该重构...但是为什么它更新了 updated_at
3 次???
注意:我试过直接调用 build_actable 而不是在控制器中更新...但它做同样的事情。我还从 Product 的 subclasses 中删除了时间戳。 我觉得我错过了一些明显的东西....
我能够通过将 touch: false
添加到作为产品子类中的关联的行为来更正两次更新时间戳的问题...
acts_as :product, touch: false