Rails:每个用于多个和一个对象数据

时间:2015-03-15 13:21:02

标签: ruby-on-rails ruby

我是rails的新手,需要清除一个问题:

例如我的方法返回这样的数据:

 #<Article ART_ID: 1151754, ART_ARTICLE_NR: "0 281 002 757", ART_SUP_ID: 30, ART_DES_ID: nil, ART_COMPLETE_DES_ID: 62395, ART_CTM: nil, ART_PACK_SELFSERVICE: 0, ART_MATERIAL_MARK: 0, ART_REPLACEMENT: 0, ART_ACCESSORY: 0, ART_BATCH_SIZE1: nil, ART_BATCH_SIZE2: nil, datetime_of_update: "2012-09-25 17:49:18">

或数组,不仅仅是一个对象:那么如何使用每个func呢?

例如:

articles = ArtLookup.search_strong_any_kind_without_brand(params[:article_nr].gsub(/[^0-9A-Za-z]/, ''))
      binding.pry
        if articles.present?
          articles.each do |a|
            @all_parts_result << 
            {
              analogue_manufacturer_name: a.supplier.SUP_BRAND,
              analogue_code: a.ART_ARTICLE_NR,
              delivery_time_min: '',
              delivery_time_max: '',
              min_quantity: '',
              product_name: a.art_name,
              quantity: '',
              price: '',
              distributor_id: '',
              link_to_tecdoc: a.ART_ID
            }
          end
        end

现在我收到了像

这样的错误
 `undefined method `each' for `#<Article:0x007f6554701640>

我认为这是因为我有时会有一个对象,有时是10个,有时是0个。

如何在铁轨中做到这一点并且是正确的?

3 个答案:

答案 0 :(得分:0)

我认为正确的做法是确保您的方法始终返回一个数组(或可枚举的)。

查看您发布到pastebin的代码我建议您在方法中使用Array#select 例如,您可能只能返回此信息:

@articles.select { |art| art.ART_ARTICLE_NR.gsub(/[^0-9A-Za-z]/, '') == search } 

假设@articles是一个数组或集合,你将总是得到一个数组,即使它是0或1个元素

答案 1 :(得分:0)

您的search_strong_any_kind_without_brand方法会根据搜索条件循环浏览您的文章。如果文章匹配,那么您将@art_concret设置为匹配,然后返回匹配。但是,你找不到所有的比赛,只是最后一场比赛。

.
loop
  @art_concret = art
end
.
return @art_concret

如果将@art_concret设置为数组并将结果注入此实例变量,那么您将以数组形式获得结果搜索。但是,请记住,这会破坏ActiveRecord ORM,因为您将返回一个简单的数组而不是ActiveRecord Relation数组。

def self.search_strong_any_kind_without_brand(search)
    search_condition = search.upcase
    @art_concret = []
    @search = find(:all, :conditions => ['MATCH (ARL_SEARCH_NUMBER) AGAINST(? IN BOOLEAN MODE)', search_condition])
    @articles = Article.find(:all, :conditions => ["ART_ID in (?)", @search.map(&:ARL_ART_ID)])
    #binding.pry
    @articles.each do |art|
      if art.ART_ARTICLE_NR.gsub(/[^0-9A-Za-z]/, '') == search
        @art_concret << art
      end
    end    
    return @art_concret
  end

如果您希望保持代码更清洁,请在匹配条件中使用select,而不是遍历@articles中的每篇文章。

def self.search_strong_any_kind_without_brand(search)
    search_condition = search.upcase
    @search = find(:all, :conditions => ['MATCH (ARL_SEARCH_NUMBER) AGAINST(? IN BOOLEAN MODE)', search_condition])
    @articles = Article.find(:all, :conditions => ["ART_ID in (?)", @search.map(&:ARL_ART_ID)])
    #binding.pry
    return @articles.select { |art| art.ART_ARTICLE_NR.gsub(/[^0-9A-Za-z]/, '') == search } 
  end

无关:你有没有在search_strong_any_kind_without_brand使用实例变量的原因?

答案 2 :(得分:0)

这个答案有点偏离,但我想提一下splat operator

[*val]

将生成数组,包括单个val值,无论它是否为数组,还是数组本身,val是否为数组:

▶ def array_or_single param
▷   [*param].reduce &:+  # HERE WE GO
▷ end  
=> :array_or_single
▶ array_or_single [1,2,3]
=> 6
▶ array_or_single 5
=> 5

那就是说,你的代码可以解决这个微小的改进:

- articles.each do |a|
+ [*articles].each do |a|

希望它能提示如何处理来自第三方的数据。作为您特定问题的答案,请按照其他答案中的建议进行操作。