trowse
trowse

Reputation: 204

Rails Search returns duplicate

I am doing an inner join (at least I think that's what the code is doing) but my search is returning the same result multiple times. I think I have something wrong with my join.

Tags

+------------+--------------+------+-----+---------+----------------+
| Field      | Type         | Null | Key | Default | Extra          |
+------------+--------------+------+-----+---------+----------------+
| id         | int(11)      | NO   | PRI | NULL    | auto_increment |
| name       | varchar(255) | YES  |     | NULL    |                |
| color      | varchar(255) | YES  |     | NULL    |                |
| article_id | int(11)      | YES  | MUL | NULL    |                |
| created_at | datetime     | NO   |     | NULL    |                |
| updated_at | datetime     | NO   |     | NULL    |                |
+------------+--------------+------+-----+---------+----------------+

Articles

+------------+--------------+------+-----+---------+----------------+
| Field      | Type         | Null | Key | Default | Extra          |
+------------+--------------+------+-----+---------+----------------+
| id         | int(11)      | NO   | PRI | NULL    | auto_increment |
| title      | varchar(255) | YES  |     | NULL    |                |
| info       | text         | YES  |     | NULL    |                |
| created_at | datetime     | NO   |     | NULL    |                |
| updated_at | datetime     | NO   |     | NULL    |                |
+------------+--------------+------+-----+---------+----------------+

Each article I have tagged and it returns multiple results based on the tags. So if the article has 3 tags this results in 3 records being returned. Even though each article should only have 1 returned?

class Article < ApplicationRecord
  has_many :tags, dependent: :destroy
  validates :title, presence: true

  def self.search(search)
  if search
    joins(:tags).where('title LIKE :search OR tags.name LIKE :search', search: "%#{search}%")
  else
    all
  end
end
end

Upvotes: 0

Views: 27

Answers (1)

duddits
duddits

Reputation: 577

Use .distinct or .group. There is .uniq alias too starting from rails 4.0.2.

Example:

joins(:tags).where('title LIKE :search OR tags.name LIKE :search', search: "%#{search}%").distinct

joins(:tags).where('title LIKE :search OR tags.name LIKE :search', search: "%#{search}%").
group('article_id')

Upvotes: 1

Related Questions