How to check if the object is in array? - ruby-on-rails

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

Related

Sort records by substring (time) of attribute

I have this active record query:
shop = Shop.find(12934)
I then go and get a collection of products from this shop like so
#product_templates = []
shop.products.each do |product|
#product_templates.push(product.template)
end
So now I have an array of active record objects which look like this:
[
#<Product::Template id: 185549, name: "1:30pm", position: 0>,
#<Product::Template id: 185522, name: "11:30am", position: 1>,
#<Product::Template id: 185580, name: "7:00pm", position: 2>,
#<Product::Template id: 185556, name: "10:00am", position: 3>,
]
I want to update the position attribute by ordering each of these Product::Template by the time in the name e.g.
10:00am, 11:30am, 1:30pm, 7:00pm would be the order of the objects so the 10:00am object would get position: 0, 7:00pm would get position:3 etc.
How would I do this? Thanks for your time in advance
try this:
#product_templates.sort { |t1, t2| Time.strptime(t1, "%I:%M%P") <=> Time.strptime(t2, "%I:%M%P") }.each_with_index { |template, index| product.position = index }
What I did there was sorting your template array first, then updating position based on array index.
First of all, your way of filling #product_templates before sort is not a good way.
#product_templates =
shop.products
.map(&:template)
.sort_by{|template| template.name.to_time}

How to merge 2 activerecord records together and be left with 1? Rails

I have 2 apples:
{
id: 1,
rotten: true,
branch_on_tree: nil,
type: "red delicious"
},
{
id: 2,
rotten: nil,
branch_on_tree: 5,
type: "red delicious"
}
They are duplicate apples for red delicious. How do I merge the records together and then delete the one with missing data? Is there a convenient way to do this?
Note: There might be like 10 duplicates. I don't want any null values in my final record. Non-null values take precedence.
Not very convinient way but it will work
assuming apples is an array:
[
{
id: 1,
rotten: true,
branch_on_tree: nil,
type: "red delicious"
},
# ...
]
that can come from:
apples = Apple.where(type: "red delicious")
apples_attrs = apples.map(&:attributes)
Then,
apple_attrs = apples_attrs.reduce do |apple, next_apple|
apple.merge(next_apple) do |_, old_value, new_value|
old_value || new_value
end
end
apples.destroy_all
Apple.create(apple_attrs)
You might want to check this guide https://apidock.com/ruby/Hash/merge
Assuming type always has some value, you can use DISTINCT with where clause. The below should work
Apple.where('rotten IS NOT NULL AND branch_on_tree IS NOT NULL').select('DISTINCT ON (type) rotten,branch_on_tree,type').take

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.

`Model.to_a.each` gives me the whole array

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']

Delete a record if nil is returned

I am making requests to the Facebook API and some of the responses are empty/nil and I am wondering how I can delete these so that when I save them to my model I don't have any nil entries.
def formatted_data
for record in results['data'] do
attrs = {
message: record['message'],
picture: record['picture'],
link: record['link'],
object_id: record['object_id'],
description: record['description'],
created_time: record['created_time']
}
attrs.delete_if { |x| x.nil? }
Post.where(attrs).first_or_create! do |post|
post.attributes = attrs
end
end
As you can see I am trying to use the delete_if method but it's not working.
Here's an example of a response that I would like to delete:
id: 45
message:
picture:
link:
object_id:
large_image_url:
description:
created_time: 2014-04-12 11:38:02.000000000 Z
created_at: 2014-05-01 10:27:00.000000000 Z
updated_at: 2014-05-01 10:27:00.000000000 Z
This kind of record is no good to me as it has no message, so maybe I could make the query specify if message.nil ? then delete
Edit
Been reading the delete_if docs and after iceman's comment, I thought this would work but it doesn't, though it seems closer to what I want:
attrs = attrs.delete_if {|key, value| key = 'message', value = nil }
There are about 25 records returned, of which 5 should be deleted, but after running the above I get one result left in the model:
[#<Post id: 81, message: nil, picture: nil, link: nil, object_id: nil, large_image_url: nil, description: nil, created_time: nil, created_at: "2014-05-01 11:22:40", updated_at: "2014-05-01 11:22:40">]
Why are all the rest being deleted, maybe my syntax for accessing the key is incorrect?
Since #delete_if passes into block two arguments: the key, and value, try this usage:
attrs.delete_if { |k,v| v.nil? }
and for ruby-on-rails you can remove all blank lines, i.e. nil, and empty:
attrs.delete_if { |k,v| v.blank? }
Im adding this in that someone could provide a more efficient way of doing this, maybe before the records get written to the model..But i have managed a solution, albeit a hacky one i would say
I have added this after the creation of the posts
delete_if_nil = Post.where(message: nil)
delete_if_nil.destroy_all
Its another query on the db which isnt ideal i guess
Any other suggestions appreciated

Resources