Create array out of data in collectioin - ruby-on-rails

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?

Related

how to make an array into array of arrays in ruby?

I have a query company_in_outs = company.in_outs.where('date >= ? and date <= ?', Date.today.at_beginning_of_month, Date.today.end_of_month) which is returning me <ActiveRecord::AssociationRelation. now i want to make this array into an array of arrays, those are grouped based on the date value.
for example.
#<ActiveRecord::AssociationRelation [#<InOut id: 2806, date: "2016-06-01", created_at: "2016-06-02 07:01:52", updated_at: "2016-06-16 07:43:45", company_id: 1>,#<InOut id: 2806, date: "2016-06-01", created_at: "2016-06-02 07:01:52", updated_at: "2016-06-16 07:43:45", company_id: 1>,#<InOut id: 2806, date: "2016-06-01", created_at: "2016-06-02 07:01:52", updated_at: "2016-06-16 07:43:45", company_id: 1>,#<InOut id: 2806, date: "2016-06-02", created_at: "2016-06-02 07:01:52", updated_at: "2016-06-16 07:43:45", company_id: 1>,#<InOut id: 2806, date: "2016-06-02", created_at: "2016-06-02 07:01:52", updated_at: "2016-06-16 07:43:45", company_id: 1>,#<InOut id: 2806, check_in: "2016-06-24 16:16:00", check_out: "2016-06-25 01:16:00", date: "2016-06-01", created_at: "2016-06-02 07:01:52", updated_at: "2016-06-16 07:43:45", company_id: 1> ]
from this array i want to make an array of arrays, which needs to be grouped based on the date. meaning all records which contains same date needs to be grouped as one array. like this i want to have an array of arrays.
If you already have all the records loaded:
company_in_outs.each_with_object({}) do |record, hash|
(hash[record.date] ||= []) << record
end.values
if you aren't using Rails (ActiveSupport) you should use inject instead of each_with_object
company_in_outs.inject({}) do |hash, record|
(hash[record.date] ||= []) << record
hash
end.values
I think you should be able to done sorting on db site too.
There is actually a group_by method in Array, but instead of returning array of array, it returns an object with key and array of the same key as value.
In your case:
company_in_outs.group_by do |com|
com.date
end
The code above will return an object grouped by date as a key, and array of the same date as value.
You could loop through the returning object which will return key and value, and do whatever you like :)
Hope this helps!

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.

Rails where clause not equal to nil

Hey folks trying to do a simple query where I find all records where a particular attribute is nil. In this case...
irb(main):009:0> Registration.where(:registration_cancellation_token != nil)
Registration Load (0.2ms) SELECT `registrations`.* FROM `registrations` WHERE (1)
=> [#<Registration id: 1, orientation_id: 13, first_name: "mark", last_name: "Busta", email: "marklocklear#gmail.com", student_id: "3232333", phone: "3884448333", registration_cancellation_token: nil, registration_cancelled_at: nil, checked_in: false, created_at: "2014-02-20 13:46:31", updated_at: "2014-02-20 13:46:31">]
...but the query is returning all registrations. Any help appreciated...
Registration.where("registration_cancellation_token IS NOT NULL")
Registration.where.not(registration_cancellation_token: nil)
This works for Rails 4

bizarre ActiveRecord equality issue

I've fixed this for my actual app fairly trivially by overriding the == operator, but it is driving me nuts and I haven't been able to find an explanation. As far as I know, ActiveRecord is supposed to determine the equality of two existing records just via the id field, right?
Apparently, no!
Loading development environment (Rails 3.0.4)
irb(main):001:0> c = ChallengeClaim.find(1)
=> #<ChallengeClaim id: 1, collection_id: 954, creation_id: nil, creation_type: nil, request_signup_id: 2, request_prompt_id: 5, claiming_user_id: 8, sent_at: nil, fulfilled_at: nil, defaulted_at: nil, created_at: "2011-09-23 04:39:07", updated_at: "2011-09-23 04:39:07">
irb(main):002:0> c2 = ChallengeClaim.find(2)
=> #<ChallengeClaim id: 2, collection_id: 954, creation_id: nil, creation_type: nil, request_signup_id: 2, request_prompt_id: 4, claiming_user_id: 8, sent_at: nil, fulfilled_at: nil, defaulted_at: nil, created_at: "2011-11-07 17:47:33", updated_at: "2011-11-07 17:47:33">
irb(main):003:0> c == c2
=> true
?!?!!??!
Any explanations gratefully welcomed so I can sleep at night again. :>
As Chris Heald pointed out above in the comments, indeed the comparison operator <=> was defined on ChallengeClaim!

Finding elements in array of hashes

I'm trying to build a model of products which has many components. Some components are optional and depend on the choice the user is making to enable them or not.
I have two models, one is configuration and the other is elements (of that configuration).
At the beginning I bring all the elements of the array, and then create another array of those which will be shown by default.
But when I write the following code it gives me an error despite both objects being arrays of hashes.
So I bring my first array of all elements:
irb(main):252:0* #all = Configuration.find(1).elements
=> [#<Element id: 1, name: "elem1", quantity: 1, position: 1, subposition: nil, created_at: nil, updated_at: nil, configuration_id: 1>, #<Element id: 2, name: "elem2", quantity: 2, position: 2, subposition: 1, created_at: nil, updated_at: nil, configuration_id: 1>, #<Element id: 3, name: "elem3", quantity: 3, position: 2, subposition: 2, created_at: nil, updated_at: nil, configuration_id: 1>, #<Element id: 4, name: "elem4", quantity: 4, position: 3, subposition: nil, created_at: nil, updated_at: nil, configuration_id: 1>]
Then I filter to be only those that have a subposition nil or 1
irb(main):253:0> #default = #all.where(:subposition=>nil).concat(#all.where(:subposition=>1))
=> [#<Element id: 1, name: "elem1", quantity: 1, position: 1, subposition: nil, created_at: nil, updated_at: nil, configuration_id: 1>, #<Element id: 4, name: "elem4", quantity: 4, position: 3, subposition: nil, created_at: nil, updated_at: nil, configuration_id: 1>, #<Element id: 2, name: "elem2", quantity: 2, position: 2, subposition: 1, created_at: nil, updated_at: nil, configuration_id: 1>]
So far so good, as you can see, Elem3 is not being shown in #default as it doesn't meet the requiements.
The problem comes when I try to play with the arrays as I need to perform certain operations.
irb(main):257:0> #all.where(:position =>1)
=> [#<Element id: 1, name: "elem1", quantity: 1, position: 1, subposition: nil, created_at: nil, updated_at: nil, configuration_id: 1>]
But the same operation in #default will fail,
irb(main):258:0> #default.where(:position =>1)
NoMethodError: undefined method `where' for #<Array:0x2641660>
Now, they're both arrays of hashes and look the same, why is the same method failing in the second case?
Thanks a lot for your help!
Throughout your code, #all is an ActiveRecord::Relation, not an array. This lets you perform the standard .where call (among others). When you assigned to #default, you used .concat which evaluated the query and assigned an actual array to #default.
You might try a different approach in your second code block. Maybe something like this:
#default = #all.where("subposition is null or subposition = ?", 1)
Well, your problem is that concat transforms a collection into an array.
I'd replace:
irb(main):253:0> #default = #all.where(:subposition=>nil).concat(#all.where(:subposition=>1))
by:
#default = #all.where("subposition = '1' OR subposition = nil") #I'm unsure of the nil in the statement, I nerver remember, try NULL if it fails
This way, you make only one db query and you keep an ActiveRecord collection.
Thus, you'll be able to chain other where conditions on it.

Resources