【问题标题】:Converting ActiveRecord object to an array将 ActiveRecord 对象转换为数组
【发布时间】:2018-05-31 19:04:32
【问题描述】:
 collected_cards.each do |card|
      ac = Card.find_by('name like ?', "#{card}")

      if ac.nil?
        next
      else
        confirmed_cards << ac
      end
    end

我正在解析一个字符串数组。对于每个字符串,我尝试从我的 postgres ac = Card.find_by('name like ?', "#{card}") 中收集一个名称

问题是,Ruby/Rails 没有将 AC 对象视为数组甚至哈希,这导致我尝试在视图中呈现它时出现此错误:

undefined method `each' for #<Card:0x007f9368494a50>

这是视图代码的小sn-p:

<% @cardset.each do |cardset| %>
  <% cardset.each do |collection| %> # I get an error here
    <h1>Cards matching <%= collection.first[:name] %></h1>
    <% collection.each do |card| %>
      <%= image_tag "#{card[:image]}" %>
      <%= card[:name] %>

cardset 应该是我遍历的哈希数组(上下文)

谢谢!

编辑:我的控制器中负责此视图的方法:

def cards
    @collection = params[:imgur_link]
    unique_path = @collection.gsub("https://imgur.com/a/", "")
    @imgur = ImgurService.new(unique_path).call
    @ocr = OcrService.new(@imgur).call
    @cardset = CardsService.new(@ocr).call
end

卡服务:

def initialize(ocrservice)
    @cards_from_ocr = ocrservice
  end

  def call
    match_ocr_with_ac
    # display_max_price
  end

  def match_ocr_with_ac
    confirmed_cards = []
    collected_cards = @cards_from_ocr

    collected_cards.each do |card|
      ac = Card.find_by('name like ?', "#{card}")

      if ac.nil?
        next
      else
        confirmed_cards << ac
      end
    end

    confirmed_cards
  end

【问题讨论】:

  • Card.find_by 的 O(n) 效率非常低。您可能需要稍微更改您的数据模型,具体取决于collected_cards 的存储/检索方式。您没有在控制器中设置 @cardset,这可能是您的错误。
  • 嘿@ThomasR.Koll 我在我的控制器中设置@cardset。 (使用 CardService 和此特定视图的控制器方法更新的原始帖子)。我认为问题在于 AC 对象解析部分。不知道在哪里。
  • Card.find_by('name like ?', "#{card}") 只返回一个元素而不是数组,这就是为什么你没有数组数组的原因。你只有一个带有 activerecord 元素的数组
  • @fanta 是也不是。如果我的数据库中只有一个具有此特定“名称”的对象,那么您是完全正确的。但是,在我的情况下,我倾向于拥有多个具有相同名称的对象(并且通过该调用,我得到了一个数组)。我的问题是,当我只有 1 个具有此特定名称的对象时会发生什么?此外,如果对象不是nil,我仍然会将其推送到稍后迭代的数组中。出于某种原因,即使我 100% 确定数据是正确的,该数组也是空的(nil)。编辑:如果我有一个 AC 元素数组,我怎么能把它变成哈希数组?
  • 为什么插值card(即find_by('name like ?', "#{card}"))可以直接使用(即find_by('name like ?', card))?此外,该查询将与 find_by(name: card) 相同,除非 card 中包含模式匹配字符,或者您的数据库的 like 不区分大小写。

标签: sql ruby-on-rails ruby activerecord


【解决方案1】:

find_by 方法查找匹配某些条件的第一条记录 (source)

如果你想将一个同名记录数组推入confirmed_cards,你应该这样做:

ac = Card.where('name like ?', "#{card}").to_a

【讨论】:

    【解决方案2】:

    假设您在cards 表中有一个名为card_text 的字段,其中包含您想要的字符串,您要查找的代码可能是:

    collected_cards.pluck(:card_text).each do |card_text|
      ac = Card.find_by('name like :pattern', pattern: "%#{card_text}%")
      next unless ac
      confirmed_cards << ac
    end
    

    confirmed_cards = collected_cards.pluck(:card_text).select do |card_text|
      Card.find_by('name like :pattern', pattern: "%#{card_text}%")
    end
    

    Pluck 将获取活动记录对象的集合并返回一个仅包含您指定的字段的数组。

    我更喜欢使用带有冒号名称语法的绑定参数,因为它与绑定参数的顺序分离。

    【讨论】:

      猜你喜欢
      • 2013-06-24
      • 1970-01-01
      • 2021-05-03
      • 2018-12-04
      • 2021-06-16
      • 1970-01-01
      • 2019-07-11
      相关资源
      最近更新 更多