包含块内目录中的所有ruby文件作为内联代码

时间:2017-07-26 13:32:10

标签: ruby-on-rails ruby

ruby​​文件的结构如下所示,

market
  |__abcd
       |__classification
              |__for_sale_mobile_phone.rb
              |__catalogues
                  |__mobile_phone_brands
                      |__acer.rb
                      |__apple.rb
                      |__samsung.rb

for_sale_mobile_phone.rb中,我希望将所有mobile_phone_brands品牌包含在一个区块内。

我试图以下面的方式包含品牌,

 .....
    c.tree_field :brand, { child_key: :model } do |b|
      Dir[
        File.dirname(__FILE__) + '/catalogues/mobile_phone_brands/*.rb'
      ].each { |brand| load brand }

      b.required = true
    end
.....

这是品牌档案的样子。例如,apple.rb

b.value "apple" do |brand|
  brand.value "6plus"
  brand.value "6s"
  brand.value "6s-plus"
  brand.value "se"
  brand.value "7"
  brand.value "7-plus"
  brand.value "other-model"
end

我遇到错误,

undefined local variable or method `b' on line 1: apple.rb

如何在块范围内包含文件?

提前致谢!

2 个答案:

答案 0 :(得分:1)

您应该将文件“加载”与函数执行分开。像这样重新定义你的文件。

class AppleLoader

  def self.load(b)
    b.value "apple" do |brand|
      brand.value "6plus"
      brand.value "6s"
      brand.value "6s-plus"
      brand.value "se"
      brand.value "7"
      brand.value "7-plus"
      brand.value "other-model"
    end
  end
end

在文件顶部加载所需的类:

require '/catalogues/mobile_phone_brands/apple_loader.rb'

如果您想在b对象中加载Apple品牌:

AppleLoader.load b

更好的方法: 对我来说,感觉Apple.rb只是在数据方面推迟Samsung.rb。如果是这种情况,并且两者的功能相同,那么我宁愿:

  1. 将该数据放入Yaml文件(brands.yml)而不是rb文件中。

        brands:
         apple: ["6plus", "6s"]
         samsung: ["galaxy"]
    
  2. 只有一个名为BrandLoader的常用加载器

    class BrandLoader
    
      def self.load(b, brand_name, values)
        b.value brand_name do |brand|
          brand_values.each do |value|
            brand.value value
          end
        end
      end
    end
    
  3. 通过阅读Yaml来讨论品牌

    configurations = YAML.load "brands.yml"
    configurations["brands"].each do |brand_name, values|
      BrandLoader.load(b, brand_name, values)
    end
    

答案 1 :(得分:0)

我想出的方法是使用eval,但谨慎阅读is-eval-supposed-to-be-nastyeval适用于我,因为我没有使用用户输入。

要在不同文件中创建任何代码,请执行在调用地点编写的代码。使用eval(File.read(file_path)

 .....
    c.tree_field :brand, { child_key: :model } do |b|
      Dir[
        File.dirname(__FILE__) + '/catalogues/mobile_phone_brands/*.rb'
      ].each { |brand| eval(File.read(brand)) }

      b.required = true
    end
.....