`Model.to_a.each` gives me the whole array - ruby-on-rails

I have a table Status already seeded. I wanted to get:
['Aberto', 'Pendente', 'Concluido', 'Fechado']
and when I type:
Status.all.to_a.each { |u| u.nome }
I get:
[#<Status id: 1, nome: "Aberto">, #<Status id: 2, nome: "Pendente">, #<Status id: 3, nome: "Concluido">, #<Status id: 4, nome: "Fechado">]
Can anyone tell me what's happening?

Array#each is used for iteration, Array#map is used to for mapping. Here you wanted to map nome to each status. Therefore, just use Array#map:
Status.all.to_a.map { |u| u.nome }
Or even better, the shortcut:
Status.all.to_a.map(&:nome)

You can use pluck
Status.pluck(:nome) # => ['Aberto', 'Pendente', 'Concluido', 'Fechado']

Related

Rails - how to fetch from ActiveRecord object only specific records?

I get this from an ActiveRecord call:
#<ActiveRecord::Associations::CollectionProxy [
#<CarService id: nil, car_id: nil, car_service: 1,
created_at: nil, updated_at: nil, car_type: 0>,
#<CarService id: nil, car_id: nil, car_service: 11,
created_at: nil, updated_at: nil, car_type: 1>]>
Once I get this, I need to filter only records where car_type = "0". How to do that without doing another database call (WHERE car_type = "0")?
Thank you in advance.
EDIT:
this:
car.car_services.select{|key, hash| hash['car_type'] == "1" }
does not work.
just convert your result to an array then filter it like this
result = car.car_services.to_a.select do |e|
e.car_type == "0"
end
You can use scope in CarService model:
scope :type_ones, -> { where(car_type: 1) }
and you can use it like this:
car.car_services.type_ones
If you use enum, it will be better. Because the enum creates to scopes automatically instead of you. And of course it has more features. More about the enum.

How to check if the object is in array?

I have an array like this:
[#<Merit::Badge id: 1, name: "just-registered", level: nil, description: nil, custom_fields: nil>,
#<Merit::Badge id: 2, name: "change-username", level: nil, description: nil, custom_fields: nil>]
How can I check if for example badge id 2 is present in the array?
If you have that model loaded in other object - just array.include?(badge), if not - array.any?{|b| b.id==2 } (but do not hardcode the id)
Assume that your array is merits, the solution should be:
merits.index { |obj| obj.id == 2 }.nil?
That line of code above check if the id of 2 NOT present in the array. Please see here for more details on the API
you can try for your active record model Merit::Badge .
Merit::Badge.exists?(badge.id)
For your case badge id 2
Merit::Badge.exists?(2)
For more on exists? you can refer: exists?
found_object = merge_barge_list.find{|merit_badge| merit_badge.id == 2}
if found_object
# object found
else
# object not found
end

Create array out of data in collectioin

I have this collection
<ActiveRecord::Associations::CollectionProxy [#<Fallower user_id: 1, author_id: 2, created_at: "2015-09-06 22:59:40", updated_at: "2015-09-06 22:59:40">, #<Fallower user_id: 1, author_id: 3, created_at: "2015-09-06 22:59:40", updated_at: "2015-09-06 22:59:40">]>
and I need to create an array/collection of only "authord_id" values.
What is the best approach how to do it?
#fallowers = Fallower.where(<something>)
#authord_ids = #fallowers.map(&:authord_id)
or
#authord_ids = Fallower.where(<something>).pluck(:authord_id)
I suggest you to use collection#pluck(:author_id)
Try:
Fallower.all.collect {|f| f.author_id}
or
Fallower.pluck :author_id
also, are you sure you mean Fallower and not Follower?

Unexpected behaviour of array.count in ruby

Hi i am using Rails3 when i puts array of subscribers like this
#subscribers = User.all
and puts it.gives me this array
[#<User id: 62, is_activated: true, subscriber: "TEST_DB2", ports_order: 100, created_at: "2012-05-21 14:47:48">, #<User id: 66, is_activated: true, subscriber: "JOHI", ports_order: 100, created_at: "2012-05-22 12:06:19">, #<User id: 68, is_activated: true, subscriber: "ALI-NAQWI", ports_order: 100, created_at: "2012-05-24 11:01:22">]
And when i give command
#subscribers.count #it give me 0 count
Why?????????
Try length instead, it can be a bug in AREL :)
That he is trying to lazy do something. He is giving back proxy object so it can be a problem there. Length will always work on your result value ~ array.

Rails 3: use contents of an array as variables in a where method

I have three models: Isbn, Sale and Channel.
Aim: to get a list in the isbns show.html.erb view which looks something like this:
Isbn: myisbn
Total sales for myisbn: 100
Myisbn sales for channel 1: 50
Myisbn sales for channel 2: 25
Myisbn sales for channel 3: 25
Here are my models.
Isbn.rb model
has_many :sales
has_many :channels, :through => :sales
Sale.rb model (has attributes sales_channel_id, isbn_id, quantity)
has_many :channels
belongs_to :isbn
Channel.rb model:
belongs_to :sale
I've been working in the isbns controller, in the show method, just to get something to work. I thought I'd refactor later - advice on whether any of this stuff should go in the model would be most welcome.
So far I've got this:
#channelisbn = Sale.where("sales_channel_id =?',1).where("isbn_id=?",3)
#channelsalesisbn = 0
#channelisbn.each {|y| #channelsalesisbn =+ y.quantity}
This successfully gets all the sales where Channel ID is 1 and ISBN id is 3. But it's not much use, as the IDs are hard coded. So I got the Channel IDs into an array:
#channellist = Channel.all
#channel = 0
#channelarray = #channellist.map {|z| #channel = z.id}
which gives me a lovely array of [1,2,3,4]
But I can't figure out how to pass the 1, then the 2, then the 3 and then the 4 into a block which can be used to look up an ISBN's sales which have that sales channel id. This is what I tried (still hardcoding the ISBN id - thought I'd tackle one problem at a time), which returned an empty array:
#channelarray.each do |channel|
#channelisbn = []
#channelisbn = Sale.where("sales_channel_id = ?", channel).where("isbn_id = ?",3)
#channelsalesisbn = 0
#result = []
#result << #channelisbn.each {|a| #channelsalesisbn =+ a.quantity}
end
I was then going to sum the contents of the array.
Any help would be gratefully received. This is my first post, so my zero acceptance rate will change soon!
UPDATE
Just to finish this question off, here's where I've ended up, which is great, and ready for tinkering with: an array, nicely grouped, giving me sales by isbn by channel. Thanks for the group_by tip off!
#in the show action in the isbns controller:
#isbn = Isbn.find(params[:id])
#channelarray = Channel.select(:id).all
#channelarray.group_by {|i| Sale.where("channel_id = ?",i).where("isbn_id =?", #isbn)}
From the console, line breaks added for clarity:
(sneakily set #isbn = 3 first of all, since in the console you can't pass params from a view, so the #isbn instance defined in the controller is nil in the console)
ruby-1.9.2-p180 :067 > #channelarray.group_by {|i| Sale.where("channel_id = ?",i).where("isbn_id =?", #isbn)}
=> {[#<Sale id: 1, isbn_id: 3, quantity: 10000, value: 12000, currency: "GBP", total_quantity: nil, created_at: "2011-05-06 12:30:35", updated_at: "2011-05-07 17:43:13", customer: "Waterstone's", retail_price: nil, discount: nil, invoice_date: "2011-05-24">, #<Sale id: 2, isbn_id: 3, quantity: 1000, value: 500, currency: "GBP", total_quantity: nil, created_at: "2011-05-07 09:37:53", updated_at: "2011-05-07 19:14:52", customer: "Borders", retail_price: nil, discount: nil, invoice_date: "2011-02-05">]=>[#<Channel id: 1>],
[#<Sale id: 3, isbn_id: 3, quantity: 500, value: 1500, currency: "", total_quantity: nil, created_at: "2011-05-07 09:38:11", updated_at: "2011-05-07 19:15:07", customer: "Borders", retail_price: nil, discount: nil, invoice_date: "2011-12-05">, #<Sale id: 4, isbn_id: 3, quantity: 45, value: 300, currency: "", total_quantity: nil, created_at: "2011-05-07 09:38:38", updated_at: "2011-05-07 19:15:36", customer: "Borders", retail_price: nil, discount: nil, invoice_date: "2011-06-05">]=>[#<Channel id: 2>],
[]=>[#<Channel id: 3>],
[]=>[#<Channel id: 4>]}
UPDATE 2
Ha, the hash I generated had the key value pairs the wrong way round. The array containing the sales data was the key - it should have been the value. Rubydocs saved the day:
#salesbychannel = #salesbychannelwrong.invert
The invert method switches the key-value pairs. Sweet.
What you're looking for is passing an array to a ARel#where(), like this:
Sale.where(:sales_channel_id => #channelarray)
This should execute an IN query. If that's not working, you can always pass the array to ActiveRecord#find, like this:
Sale.find(#channelarray)
Hope this helps

Resources