在模型中确定哪个控制器触发保存操作?
Determine in model that which controller is trigger the save action?
正在为 api 和前端开发 rails 应用程序。所以我们有 api 的产品控制器和前面的产品控制器,产品模型是两者的一个。
像那样
class Api::V1::ProductsController < ActionController::API
def create
@product.save
end
end
class ProductsController < ActionController::Base
def create
@product.save
render @product
end
end
class Product < ActiveRecord::Base
def weight=(value)
weight = convert_to_lb
super(weight)
end
end
基本上在产品中我们有 'weight field',这个字段基本上是从仓库中捕获重量。对于用户来说,这将是不同的单位。所以我将保存按单位捕获的任何重量,它的 lb、g 或 stone 但它会转换为 lb 并存储到数据库中。
所以我为对话编写了覆盖方法。但我希望这个覆盖方法应该只调用前端应用程序而不是 api。因为 api 总是 post 以磅为单位的重量(需要在客户端进行转换)
你们有谁能提出解决方案吗?对于这种 scenario.suggest 我应该使用什么或者我应该做什么,如果它也适用于这种情况的任何其他解决方案。提前致谢。
最好保持 Product
模型尽可能简单 (Single-responsibility principle) 并将重量转换放在外面。
我认为使用 Decorator 模式会很棒。想象一下 class 是这样工作的:
@product = ProductInKilogram.new(Product.find(params[:id]))
@product.update product_params
@product.weight # => kg weight here
因此,您应该只使用来自 Api::V1::ProductsController
的新 ProductInKilogram
。
您可以选择实现它。
继承
class ProductInKilogram < Product
def weight=(value)
weight = convert_to_lb
super(weight)
end
end
product = ProductInKilogram.find(1)
product.weight = 1
很简单,但是 ProductInKilogram 的复杂度很高。例如,您无法在没有数据库的情况下在隔离环境中测试此类 class。
简单委托人
class ProductInKilogram < SimpleDelegator
def weight=(value)
__getobj__.weight = convert_to_lb(value)
end
end
ProductInKilogram.new(Product.find(1))
普通 Ruby(我的最爱)
class ProductInKilogram
def initialize(obj)
@obj = obj
end
def weight=(value)
@obj.weight = convert_to_lb(value)
end
def weight
convert_to_kg @obj.weight
end
def save
@obj.save
end
# All other required methods
end
看起来有点冗长,其实很简单。测试这样的 class 非常容易,因为它对持久性没有任何影响。
链接
正在为 api 和前端开发 rails 应用程序。所以我们有 api 的产品控制器和前面的产品控制器,产品模型是两者的一个。
像那样
class Api::V1::ProductsController < ActionController::API
def create
@product.save
end
end
class ProductsController < ActionController::Base
def create
@product.save
render @product
end
end
class Product < ActiveRecord::Base
def weight=(value)
weight = convert_to_lb
super(weight)
end
end
基本上在产品中我们有 'weight field',这个字段基本上是从仓库中捕获重量。对于用户来说,这将是不同的单位。所以我将保存按单位捕获的任何重量,它的 lb、g 或 stone 但它会转换为 lb 并存储到数据库中。
所以我为对话编写了覆盖方法。但我希望这个覆盖方法应该只调用前端应用程序而不是 api。因为 api 总是 post 以磅为单位的重量(需要在客户端进行转换)
你们有谁能提出解决方案吗?对于这种 scenario.suggest 我应该使用什么或者我应该做什么,如果它也适用于这种情况的任何其他解决方案。提前致谢。
最好保持 Product
模型尽可能简单 (Single-responsibility principle) 并将重量转换放在外面。
我认为使用 Decorator 模式会很棒。想象一下 class 是这样工作的:
@product = ProductInKilogram.new(Product.find(params[:id]))
@product.update product_params
@product.weight # => kg weight here
因此,您应该只使用来自 Api::V1::ProductsController
的新 ProductInKilogram
。
您可以选择实现它。
继承
class ProductInKilogram < Product
def weight=(value)
weight = convert_to_lb
super(weight)
end
end
product = ProductInKilogram.find(1)
product.weight = 1
很简单,但是 ProductInKilogram 的复杂度很高。例如,您无法在没有数据库的情况下在隔离环境中测试此类 class。
简单委托人
class ProductInKilogram < SimpleDelegator
def weight=(value)
__getobj__.weight = convert_to_lb(value)
end
end
ProductInKilogram.new(Product.find(1))
普通 Ruby(我的最爱)
class ProductInKilogram
def initialize(obj)
@obj = obj
end
def weight=(value)
@obj.weight = convert_to_lb(value)
end
def weight
convert_to_kg @obj.weight
end
def save
@obj.save
end
# All other required methods
end
看起来有点冗长,其实很简单。测试这样的 class 非常容易,因为它对持久性没有任何影响。