【问题标题】:Rails Concern dynamic relationRails关注动态关系
【发布时间】:2016-04-01 13:27:37
【问题描述】:

我为 rails 编写了一个 gem 来拥有一个小型的 mongoid 购物车。

在它获得的模型中通过包含 include MongoidCart::ActsAsProduct 来实现

class MyProduct
   include Mongoid::Document

   include MongoidCart::ActsAsProduct
end


module MongoidCart
  class CartItem
    include Mongoid::Document

    belongs_to :mongoid_cart_cart, :class_name => 'MongoidCart::Cart'
  end
end


module MongoidCart
  class Cart
    include Mongoid::Document

    field :user_id, type: String

    has_many :cart_items, :inverse_of => :cart, :class_name => 'MongoidCart::CartItem'
    belongs_to :customer, :inverse_of => :carts, :class_name => MongoidCart.configuration.customer_model_name

  end
end

我无法将我的Product-class 的class_name 引入CartItem-class。 它应该会自动添加到MongoidCart::CartItemclass 的关系。 当我“硬编码”为:my_product 时,没有错误。

如何使:the_class_to_point_to_as_symbol 动态化?

module MongoidCart
  module ActsAsProduct
    extend ActiveSupport::Concern

    included do

      #adds dynamic association to the CartItem to refer to the ActsAsProduct class
      MongoidCart::CartItem.class_eval(
        'belongs_to :the_class_to_point_to_as_symbol, :class_name => "Product", inverse_of: :cart_item'
      )
    end
  end
 end

【问题讨论】:

    标签: ruby-on-rails ruby mongoid activesupport activesupport-concern


    【解决方案1】:

    我最终创建了一个新类来生成字符串,该字符串由class_eval 解释并在范围之外调用它们并将字符串放入变量中:

    module MongoidCart
      module ActsAsProduct
        extend ActiveSupport::Concern
    
        included do
    
          # adds dynamic association to the CartItem to refer to the ActsAsProduct class
          relation_method = MongoidCart::Relation.build_product_relation_string(name)
          MongoidCart::CartItem.class_eval(relation_method)
      end
    end
    
    
    
    module MongoidCart
      class Relation
    
        # creates a string which can be implemented in models to provide dynamcic relation
        def self.build_product_relation_string(class_name)
          "belongs_to "+ ":#{class_name.to_s.underscore.to_sym}" + ", :class_name => '#{class_name.constantize}', inverse_of: :cart_item"
        end
    
      end
    end
    

    【讨论】:

      【解决方案2】:

      included{} 块内的self 是包含的类,因此您可以执行类似的操作

      included do
        MongoidCart::CartItem.add_product_relation(self)
      end
      

      MongoidCart::CartItem:

      def self.add_product_relation cls
        belongs_to cls.name.to_s.underscore.to_sym, class_name:cls, inverse_of: :cart_item
      end
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-03-21
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多