【问题标题】:Rails 3 Shopping Cart Design QuestionsRails 3 购物车设计问题
【发布时间】:2011-06-01 04:24:42
【问题描述】:

我有一个 Transactions 对象(作为购物车的一部分),它属于另外两个对象 Products 和 Services。产品和服务都嵌套在事务中,以创建像 /products/1/transactions/new 和 /services/1/transactions/new 这样的 URL。而且,表单是使用 form_for [@product, @transaction] do |f| 创建的。类型格式。注意:产品和服务的设计和功能差异太大,无法将它们组合成一个 STI 类型的单个对象。

我的问题是:在没有 STI 的情况下,有没有更好的方法来做到这一点?而且,检查控制器以确定要作用的对象类型的最佳方法是什么?

IE 中的新操作:

if ???
  @product = Product.find(params[:product_id])
  @transaction = @product.transactions.build
elsif ???
  @service = Service.find(params[:service_id])
  @transaction = @service.transactions.build
end

在相关的说明中,是否有人知道任何讨论 Rails 3 购物车设计的教程?我在书中看到过一些,但他们使用会话来存储整个购物车对象,在我看来这不是很安全。而且,其他人过于简单化了。

任何帮助将不胜感激!

【问题讨论】:

    标签: ruby-on-rails-3 e-commerce


    【解决方案1】:

    我认为您在这里有两个基本选择。

    (1) 创建两种交易类型/模型:product_transactions 和 service_transactions。两者都可以从一个公共事务模块继承。这种方法使您可以忽略“我正在处理哪种交易?”的问题。并关注事务模块中常见的实现细节。然后,您可以维护两个更简单的嵌套控制器,/products/<id>/transactions/services/<id>/transactions,它们不需要类型检查。

    (2) 将类型检查移到通用事务模型中。这种方法假定事务与产品或服务之间的交互将通过事务模块处理,因此您无需负责知道您正在与哪个交互。例如:

    class Transaction
      belongs_to :service
      belongs_to :product
    
      def parent
        @parent ||= product || service
      end
    
      def call_some_action_on_parent
        parent.some_action
      end
    end
    

    您可以在控制器中执行类似的操作:

    @parent = params[:service_id].blank? ? Product.find(params[:product_id]) : Service.find(params[:service_id])
    @transaction = @parent.transactions.build(params[:transaction])
    

    您确定的选项实际上应该是根据您对交易对象的需求做出的决定。如果有很多自定义代码取决于您是否与产品或服务交互,您应该遵循第一种方法。如果代码本质上是相同的,你应该采用第二种方法,专注于交易与其父对象(产品、服务或其他)之间的契约,而忽略对象类型是什么。本质上,您只关心父对象是否响应特定方法,而不关心它实际上是什么类型的对象。作为一般规则,尽可能避免类型检查并专注于 responds_to?方法来代替。

    【讨论】:

    • 感谢您非常详细的回答和解释!这是一个很大的帮助!
    • 对此我有一个后续问题。我把它放在我的控制器中(作为 before_filter 函数):@parent = params[:product_id].blank? ? Service.find(params[:service_id]):Product.find(params[:product_id])。但是,在创建操作 (@transaction = @parent.transactions.build(params[:transaction])) 中,尝试为服务创建新事务时出现错误“找不到没有 ID 的服务”。你知道为什么会这样吗?
    • 记录 params[:service_id] 的值,如果它是 nil 或空白,那么您没有传递 service_id 或 product_id。确保路径参数正确。
    • 啊哈,我将传递事务表单的@service 对象更改为新的@parent 对象并且它起作用了。再次感谢!
    猜你喜欢
    • 1970-01-01
    • 2011-08-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多