Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to pluck or select values from a database and return separate arrays for each record in rails

i have a model History(data:text) and the data is an serialized array

I want to render the all of the saved histories as json; however calling the records forces them into 1 array when I need each history to be contained in a separate hash.

When I call:

History.limit(1).pluck(:data)

everything is fine because I get 1 array:

[{"miners"=>{},
  "stats"=>
   {"amtDue"=>422770422,
    "amtPaid"=>0,
    "hash"=>18,
    "identifier"=>"global",
    "invalidShares"=>1,
    "lastHash"=>1515350526,
    "timeout"=>1515350582003,
    "totalHashes"=>7107814,
    "txnCount"=>0,
    "validShares"=>9598},
  "ticker"=>
   {"base"=>"XMR",
    "change"=>"-5.01749443",
    "price"=>"396.34459617",
    "target"=>"USD",
    "volume"=>"24647.97760706"},
  "timestamp"=>1515350523}]

However, when I call 2 or more records they are contained in 1 array which won't work for my needs:

History.limit(2).pluck(:data)

[{"miners"=>{},
  "stats"=>
   {"amtDue"=>422770422,
    "amtPaid"=>0,
    "hash"=>18,
    "identifier"=>"global",
    "invalidShares"=>1,
    "lastHash"=>1515350526,
    "timeout"=>1515350582003,
    "totalHashes"=>7107814,
    "txnCount"=>0,
    "validShares"=>9598},
  "ticker"=>
   {"base"=>"XMR",
    "change"=>"-5.01749443",
    "price"=>"396.34459617",
    "target"=>"USD",
    "volume"=>"24647.97760706"},
  "timestamp"=>1515350523},
 {"miners"=>{},
  "stats"=>
   {"amtDue"=>422770422,
    "amtPaid"=>0,
    "hash"=>4,
    "identifier"=>"global",
    "invalidShares"=>1,
    "lastHash"=>1515353143,
    "timeout"=>1515353179152,
    "totalHashes"=>7125334,
    "txnCount"=>0,
    "validShares"=>9628},
  "ticker"=>
   {"base"=>"XMR",
    "change"=>"3.74386788",
    "price"=>"405.10595848",
    "target"=>"USD",
    "volume"=>"25292.54683583"},
  "timestamp"=>1515353103}]

How do I get data for each history in a separate hash? Here's my controller, I want to render the arrays as json:

def inquiry
@step = inquiry params[:step]
@n = inquiry_params[:n]

if @n.present?
  @history = History.limit(@n).pluck[:data]
  render :json => @history
else
....
end

 def inquiry_params
    accessible = [:step, :n]
    params.permit(accessible)
  end

edit: I'm now calling :

@history = Hash[History.limit(@n).pluck(:data).flatten.map{ |el| [el] }].flatten

I get the desired format; however there is an unwanted "null" that I don't understand where it comes from or how to get rid.

[{"miners"=>["b9aeff80-e16d-4af6-b675-9f218eff8077"],
  "stats"=>
   {"amtDue"=>422770422,
    "amtPaid"=>0,
    "hash"=>28,
    "identifier"=>"global",
    "invalidShares"=>1,
    "lastHash"=>1515435268,
    "timeout"=>1515435354059,
    "totalHashes"=>9370026,
    "txnCount"=>0,
    "validShares"=>11999},
  "ticker"=>
   {"base"=>"XMR",
    "change"=>"1.18426262",
    "price"=>"383.96558958",
    "target"=>"USD",
    "volume"=>"24605.93213606"},
  "timestamp"=>1515435302},
 nil,
 {"miners"=>["b9aeff80-e16d-4af6-b675-9f218eff8077"],
  "stats"=>
   {"amtDue"=>422770422,
    "amtPaid"=>0,
    "hash"=>28,
    "identifier"=>"global",
    "invalidShares"=>1,
    "lastHash"=>1515435467,
    "timeout"=>1515435505244,
    "totalHashes"=>9374886,
    "txnCount"=>0,
    "validShares"=>12005},
  "ticker"=>
   {"base"=>"XMR",
    "change"=>"0.52934940",
    "price"=>"383.31067636",
    "target"=>"USD",
    "volume"=>"24591.95015563"},
  "timestamp"=>1515435422},
 nil]
like image 929
yrral Avatar asked Jan 08 '18 16:01

yrral


People also ask

What does pluck do in Rails?

In Rails, pluck is a shortcut to select one or more attributes without loading the corresponding records just to filter out the selected attributes. It returns an Array of attribute values.

What is an active record relation?

An instance of ActiveRecord::Base is an object that represents a specific row of your database (or might be saved into the database). Whereas an instance of ActiveRecord::Relation is a representation of a query that can be run against your database (but wasn't run yet).

What is Active Record Ruby?

1 What is Active Record? Active Record is the M in MVC - the model - which is the layer of the system responsible for representing business data and logic. Active Record facilitates the creation and use of business objects whose data requires persistent storage to a database.


1 Answers

I'm not sure if I understood you correctly but it's possible to use map like this:

2.5.0 :001 > z = [ {:s=>{:a=>1, :b=>2}}, {:t=>{:c=>3, :d=>4}} ]
   => [{:s=>{:a=>1, :b=>2}}, {:t=>{:c=>3, :d=>4}}] 
2.5.0 :002 > z.map{ |el| [el] }
   => [[{:s=>{:a=>1, :b=>2}}], [{:t=>{:c=>3, :d=>4}}]]

In your case it should then be History.limit(2).pluck(:data).map{ |el| [el] }

EDIT: By calling compact you will have your result-array with all the nil values removed like this:

2.5.0 :003 > x = [{a: {b: 1, c: 2}}, nil]
    => [{:a=>{:b=>1, :c=>2}}, nil]
2.5.0 :004 > x.compact
    => [{:a=>{:b=>1, :c=>2}}]
like image 198
Andres Avatar answered Nov 15 '22 23:11

Andres