user9850109
user9850109

Reputation:

Converting ActiveRecord object to an array

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

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

I'm parsing an array of strings. For each string i try to collect a name from my postgres ac = Card.find_by('name like ?', "#{card}")

The problem is, the AC object is not being perceived as an array or even a hash by Ruby/Rails, which leads me to this error when I try to render it in my view:

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

Here's a small snippet of the view code:

<% @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 should be an array of array of hashes that I iterate through (context)

Thanks!

Edit: Method in my controller responsible for this view:

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

CardService:

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

Upvotes: 0

Views: 78

Answers (2)

Marlin Pierce
Marlin Pierce

Reputation: 10089

Assuming you there is a field in the cards table named card_text which has the string you want, the code you are looking for might be:

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

or

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

Pluck will take a collection of active record objects and return an array of just the field(s) you specified.

I like using bound parameters with the colon-name syntax better, because it decouples from the order of the bound parameters.

Upvotes: 0

Sovalina
Sovalina

Reputation: 5609

The find_by method finds the first record matching some conditions (source)

If you want to push into confirmed_cards an array of records with the same name you should do:

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

Upvotes: 2

Related Questions