0

I'm creating a sticker album and I need to scope repeated stickers. I still can't fully understand scopes in rails. How can I create a scope that gets all the repeated stickers from a user?

Figurinha has a colada Boolean attribute, which means the sticker is placed or not in the album.

Dep is the players database, Figurinha get the name, avatar and others info from Dep model.

repetida is the method I was trying to create to check if the figurinha is repeated or not.

A figurinha is repeated when Figurinha has another record with the same user and dep which is already been colada

User.rb

class User < ActiveRecord::Base
  has_many :figurinhas
end

Figurinha.rb

class Figurinha < ActiveRecord::Base
  belongs_to :user
  belongs_to :dep
  
  def repetida
    coladas = self.user.figurinhas.where(colada: true)
    colodas.map{|a| a.dep}.include?(self.dep)
  end
  
end

Dep.rb

class Dep < ActiveRecord::Base
  has_attached_file :avatar
  validates_attachment_content_type :avatar, :content_type => ["image/jpg", "image/jpeg", "image/png", "image/gif"]
  
  belongs_to :partido, foreign_key: :partido, primary_key: :sigla

  def avatar_from_url(url)
    self.avatar = open(url)
  end
end
1
  • Dep is the players database, Figurinha get the name, avatar and others infos from Dep database. Commented Apr 20, 2016 at 14:25

2 Answers 2

1

If figurinha can only have one true colada per user you can try this :

scope :repetida, ->(user_id) { uniq.where(user_id: user_id, colada: false, dep_id: Figurinha.where(user_id: user_id, colada: true).pluck(:dep_id)) }
Sign up to request clarification or add additional context in comments.

2 Comments

Works perfectly. Can you explain to me the use of pluck method?
you can read about pluck here apidock.com/rails/ActiveRecord/Calculations/pluck it returns an array of attribute values. in your case the attribute is dep_id
1

Replace

def repetida
  coladas = self.user.figurinhas.where(colada: true)
  colodas.map{|a| a.dep}.include?(self.dep)
end

with:

scope :repetida, ->(user_id) {where(user_id: user_id).group(:dep_id).having("count(*) > 1").having("bool_or(colada) =true") }

and call should be:

Figurinha.repetida(User.first.id)

which is trying to select all Figurinha which belongs to user_id and then grouping them with dep_id so we now have groups of repeated Figurinha but we only need if the count of the group is > 1 to consider a duplicate.

6 Comments

We are almost there. The user can only have one figurinha of the same dep with colada=true.
ok, then you need to remove colada=true from the where statement
@ViniciusFontoura let's see if that work with you having("bool_or(colada) =true") we get all colada from the groups records and check if oring them will give us true that mean 1 of them is true which mean 1 of them is colada, and when you render your records skip the one with true(the main colada)
I'm getting this error now: SQLite3::SQLException: no such column: true: SELECT "figurinhas".* FROM "figurinhas" WHERE "figurinhas"."user_id" = ? GROUP BY "figurinhas"."dep_id" HAVING count(*) > 1 AND bool_or(colada) =true
you are using sqllite then true and false is 1 and 0 replace true with 1
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.