How the find the records which are not duplicates - ruby-on-rails

I have a table which will have possible duplicate records.
id: 24,
name: "vamsi",
mobile: "7639817688",
company: "digi",
requirement: "mobile app",
created_at: Wed, 12 Oct 2016 11:05:33 UTC +00:00,
updated_at: Wed, 12 Oct 2016 11:05:33 UTC +00:00,
email_sent: false>,
#<Contact:0x00000006d7a4f0
id: 25,
name: "vamsi",
mobile: "7639817688",
company: "digi",
requirement: "mobile app",
created_at: Wed, 12 Oct 2016 11:05:57 UTC +00:00,
updated_at: Wed, 12 Oct 2016 11:05:57 UTC +00:00,
email_sent: false>]
Now I would like to find the unique records on which email_sent is false. I have tried this
Contact.where(email_sent: false).distinct
Contact Load (0.4ms) SELECT DISTINCT "contacts".* FROM "contacts" WHERE "contacts"."email_sent" = $1 [["email_sent", false]]
=> [#<Contact:0x00000006a1a698
id: 25,
name: "vamsi",
mobile: "7639817688",
company: "digi",
requirement: "mobile app",
created_at: Wed, 12 Oct 2016 11:05:57 UTC +00:00,
updated_at: Wed, 12 Oct 2016 11:05:57 UTC +00:00,
email_sent: false>,
#<Contact:0x00000006a1a418
id: 24,
name: "vamsi",
mobile: "7639817688",
company: "digi",
requirement: "mobile app",
created_at: Wed, 12 Oct 2016 11:05:33 UTC +00:00,
updated_at: Wed, 12 Oct 2016 11:05:33 UTC +00:00,
email_sent: false>]
But I would not want 2 records, since both are same. I would like only one to be shown. Is there any way I can solve this.

First part, the model should have validations so that these kinds of data won't be stored
It can be done via this
validates_uniqueness_of :name, scope: [:mobile, :requirement, :company]
Second part, still if you want to query something like above scenario. You have to do this
Contact.select(:name, :company, :mobile, :requirement).where(email_sent: false).distinct would be the query
ps: Answer picked up from all the comments in the question

Try group by email_sent after using where:
Contact.where(email_sent: false).group(:email_sent)

Related

How to display all association collection in rails console?

I'd like to display in rails console all the collections of the parent entity "Article", which would be a relationship between itself, example:
# article.rb
class Article < ActiveRecord::Base
belongs_to :parent, :class_name => 'Article', optional: true
has_many :sub_articles, :class_name => 'Article', :foreign_key => 'parent_id'
end
Now what I have is:
irb(main):095:0> Article.find(1)
Article Load (0.9ms) SELECT "articles".* FROM "articles" ORDER BY
"articles"."id" ASC LIMIT $1 [["LIMIT", 1]]
=>
#<Articles:0x0000264231faa292
id: 1,
name: "king article"
created_at: Fri, 13 Aug 2021 13:14:26.463429000 UTC +00:00,
updated_at: Fri, 13 Aug 2021 13:14:26.463429000 UTC +00:00,
parent_id: nil
What I'd like to display on the rails console:
id: 1,
name: "king article"
created_at: Fri, 13 Aug 2021 13:14:26.463429000 UTC +00:00,
updated_at: Fri, 13 Aug 2021 13:14:26.463429000 UTC +00:00,
parent_id: nil
sub_articles:
[ Article:0x0000641428defb71
id: 2,
name: "pencils article"
created_at: Fri, 13 Aug 2021 13:14:26.463429000 UTC +00:00,
updated_at: Fri, 13 Aug 2021 13:14:26.463429000 UTC +00:00,
parent_id: 1
sub_articles:
[ Article:0x0000621438defb71
id: 3,
name: "pencil child 1"
created_at: Fri, 13 Aug 2021 13:14:26.463429000 UTC +00:00,
updated_at: Fri, 13 Aug 2021 13:14:26.463429000 UTC +00:00,
parent_id: 2
sub_articles: [],
id: 4,
name: "pencil child 2"
created_at: Fri, 13 Aug 2021 13:14:26.463429000 UTC +00:00,
updated_at: Fri, 13 Aug 2021 13:14:26.463429000 UTC +00:00,
parent_id: 2
sub_articles: []
]
]
Ultimately what I am looking for is if a parent is consulted to show their children (and the children of the children if possible)
It's probably best achieved by calling to_json on the top-level article, and configuring the as_json method of Article to include sub_articles
class Article < ActiveRecord::Base
def as_json(options={})
super(methods: [:subarticles])
end
end
in the rails console:
$> Article.find(3).to_json # => should give you the hierarchy you're looking for

Search for all records that have a particular value using case insensitive in a JSONB array field

I'm using postgres database and trying to query all records with "Value"=>"Black" in this JSONB field. That field contain an array of objects, e.g. {"id"=>"1", "key"=>"size", "value"=>"P"}
How do I query(case-insensitive) this records?
This is my code so far
def by_feature_value(value)
relation.where('features #> ?', [{ value: value }].to_json)
end
Records
#<ProductSku:0x000055de9cc01ba8
id: 33,
product_id: 3,
code: "1234",
ean: "12345",
created_at: Mon, 30 Apr 2018 11:47:00 UTC +00:00,
updated_at: Mon, 30 Apr 2018 11:47:00 UTC +00:00,
features: [{"id"=>"2", "key"=>"Color", "Value"=>"Black"}]>
#<ProductSku:0x000055de9cc01ba8
id: 33,
product_id: 3,
code: "1234",
ean: "12345",
created_at: Mon, 30 Apr 2018 11:47:00 UTC +00:00,
updated_at: Mon, 30 Apr 2018 11:47:00 UTC +00:00,
features: [{"id"=>"2", "key"=>"Color", "Value"=>"black"}]>,
The correct answer to this is
ProductSku.where('lower(features::text)::jsonb #> lower(?)::jsonb', [{ Value: value }].to_json)
Without type casting the first comment on your post does not work.

ActiveRecord Joins is not fetching data from multiple table. It is working for manual execution

I am building a RestAPI using Rails 5. I have 3 tables currently
Members
ContactSource (name)
ContactSourceMemberMap (member_id, contact_source_id, value)
Where,
class ContactSourceMemberMap < ApplicationRecord
belongs_to :member
belongs_to :contact_source
end
Now I want to fetch name from ContactSource and value from ContactSourceMemberMap.
I tried:
ContactSource.eager_load(:contact_source_member_maps).select("contact_sources.name", "contact_source_member_maps.value")
on ContactSourceMemberMap model.
The SQL which is getting generating is fetching data by performing INNER JOIN. But on the rails end its coming like
[#<ContactSource:0x007fa14f261950
id: 1,
name: "ContactSource1",
created_at: Thu, 08 Mar 2018 16:33:00 UTC +00:00,
updated_at: Thu, 08 Mar 2018 16:33:00 UTC +00:00>,
#<ContactSource:0x007fa14f200290
id: 2,
name: "ContactSource2",
created_at: Thu, 08 Mar 2018 16:33:00 UTC +00:00,
updated_at: Thu, 08 Mar 2018 16:33:00 UTC +00:00>,
#<ContactSource:0x007fa14fa8fb18
id: 3,
name: "ContactSource3",
created_at: Thu, 08 Mar 2018 16:33:00 UTC +00:00,
updated_at: Thu, 08 Mar 2018 16:33:00 UTC +00:00>,
#<ContactSource:0x007fa14fa8f2d0
id: 4,
name: "ContactSource4",
created_at: Thu, 08 Mar 2018 16:33:00 UTC +00:00,
updated_at: Thu, 08 Mar 2018 16:33:00 UTC +00:00>]}]
It is not displaying the value field. Any thoughts why is it behaving like that?
contact_sources = ContactSource.eager_load(:contact_source_member_maps).select("contact_sources.name", "contact_source_member_maps.value")
and then you can get the other object with
contact_sources.first.contact_source_member_maps
if I am wrong you can check the following guide

custom ordering activerecord data in rails

I have 3 courses A(july 1), B(july 2), C(july 3).A and B is rated 4 and C is rated 5.
I want to order the course like this
C should come first because it was created latest and it has higher rating than others.
A should come second because it was created first than B
I cant use order because it wont give me what i need. any way to fix this?
Here is how i am fetching the data
#courses.order('updated_at DESC, average_rating DESC')
code
[
#<Course:0x00000009f3c128
id: 6,
tutor_id: 2,
course_name: "name",
course_subtitle: "sub",
course_description: "<p>test</p> test\r\n",
video_link: "https://www.youtube.com/watch?v=UVrQcieqD0U",
course_language: "German",
course_image: "finalse.png",
created_at: Tue, 11 Jul 2017 05:03:03 UTC +00:00,
updated_at: Tue, 11 Jul 2017 08:47:03 UTC +00:00,
status: "accepted",
average_rating: 2.5,
rated_time: nil>,
#<Course:0x00000008139608
id: 7,
tutor_id: 2,
course_name: "another",
course_subtitle: "another subtuitle",
course_description: "<p>course descrition</p>\r\n",
video_link: "https://www.youtube.com/watch?v=uaTeZA-Gj7s",
course_language: "Chinese",
course_image: nil,
created_at: Tue, 11 Jul 2017 10:40:45 UTC +00:00,
updated_at: Tue, 11 Jul 2017 10:41:06 UTC +00:00,
status: "accepted",
average_rating: 2.5,
rated_time: nil>,
#<Course:0x0000000813bea8
id: 8,
tutor_id: 2,
course_name: "asfas",
course_subtitle: "were",
course_description: "<p>asdfsadf</p>\r\n",
video_link: "https://www.youtube.com/watch?v=xGytDsqkQY8",
course_language: "English",
course_image: nil,
created_at: Wed, 12 Jul 2017 03:53:26 UTC +00:00,
updated_at: Wed, 12 Jul 2017 04:32:33 UTC +00:00,
status: "accepted",
average_rating: 1.0,
rated_time: nil>,
Try:
Course.all.order("average_rating DESC, created_at ASC")
try
Course.order({ created_at: :desc, rating: :desc })
This will sort first on created_at and if two records have same created_at the will sort on the basis of rating

How to group date by day and sum in postgres?

I got this model:
[#<Account:0x007fcf32153098
id: 1,
profit: 100,
user_id: 1,
created_at: Sun, 15 Nov 2015 02:27:43 UTC +00:00,
updated_at: Sun, 15 Nov 2015 02:27:43 UTC +00:00>,
#<Account:0x007fcf32152df0
id: 2,
profit: 500,
user_id: 1,
created_at: Sun, 16 Nov 2015 15:05:07 UTC +00:00,
updated_at: Sun, 15 Nov 2015 15:05:07 UTC +00:00>,
]
And for now I got this to group them in date:
Account.all.group_by{|a| a.created_at.strftime("%Y-%m-%d")}
{"2015-11-15"=>
[#<Account:0x007fcf3247b1a8
id: 1,
profit: 100,
user_id: 1,
created_at: Sun, 15 Nov 2015 02:27:43 UTC +00:00,
updated_at: Sun, 15 Nov 2015 02:27:43 UTC +00:00>],
"2015-11-16"=>
[#<Account:0x007fcf3247afc8
id: 2,
profit: 500,
user_id: 1,
created_at: Sun, 16 Nov 2015 15:05:07 UTC +00:00,
updated_at: Sun, 15 Nov 2015 15:05:07 UTC +00:00>]}
My question is: How can I group them and at the same time sum the profit together if there are more than one record for that day? Seems like I can't use sum(:profit) with postgres?
I think you can just do this simply with:
Account.order("DATE(created_at)").group("DATE(created_at)").sum(:profit)

Resources