Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

with_any_role(:role1, :role2) on User Object returns Array instead of ActiveRecord::Relation #292

Open
FreeApophis opened this issue Oct 20, 2014 · 16 comments · May be fixed by #441
Open

Comments

@FreeApophis
Copy link

with_any_role(:role1, :role2) on User Object returns Array instead of ActiveRecord::Relation

This is a rather tiny issue, but it is rather surprising, since with_role already correctly returns a Relation Object which you can easily chain.
The problem showed up when I chained other Database scopes, and the temporary solution is to do the with_any_role at the end of the chain. This conflicts with other scopes like pagination, and of course the Array cannot be evaluated lazily.

@wldcordeiro
Copy link
Member

Thanks for reporting this! We'll get this fixed up for the next release.

@wldcordeiro wldcordeiro added this to the rolify 3.5 milestone Oct 20, 2014
@wldcordeiro wldcordeiro modified the milestones: rolify 3.5, rolify 4.0 Jan 8, 2015
@fabn
Copy link

fabn commented Oct 14, 2015

The same is true for with_all_roles. Is there any workaround?

@EppO
Copy link
Member

EppO commented Oct 15, 2015

You can combine ActiveRecord relations using .merge that combines WHERE clauses using AND which is not helping in that case (we need to OR the different WHERE clauses). With the upcoming Rails 5 release, we will be able to combine two ActiveRecord relation with OR (read this article for more info). I don't see any workaround for Rails <=4.x except playing with Arel directly.

@dkniffin
Copy link
Collaborator

dkniffin commented Mar 3, 2017

Has there been any progress on this? I was really hopeful that this method would do exactly what I wanted, but then I saw it was an array, which prevented me from chaining it with other queries.

@dkniffin
Copy link
Collaborator

dkniffin commented Mar 3, 2017

Alright, I figured out a way to fix this method. I've got a PR open now (#441)

@nhattan
Copy link

nhattan commented Aug 18, 2017

workaround

# user.rb
scope :with_any_roles, ->(names) do
  joins(:roles).where("roles.name IN (?)", names)
end

# using
User = User.with_any_roles([:admin, :moderator])

@kakoni
Copy link

kakoni commented Dec 1, 2017

@nhattan If user has multiple roles, then with that query you will get duplicate rows. Of course User.with_any_roles([:admin, :moderator]).distincthelps

@Mehonoshin
Copy link

Mehonoshin commented Jun 11, 2018

Still not released?

@nhattan
Copy link

nhattan commented Jun 11, 2018

Thanks @kakoni

@mendelk
Copy link

mendelk commented Jul 29, 2018

Any update on this?

@EppO
Copy link
Member

EppO commented Feb 27, 2019

WIP here #441

TL;DR: Works with Rails 4.2 but not (yet) on Rails 5

@EppO EppO removed 3.x labels Feb 28, 2019
@milani
Copy link

milani commented May 22, 2019

@kakoni just be aware that the workaround does not work when there is a column with type json. DISTINCT raises an exception in that case.

@milani
Copy link

milani commented May 22, 2019

@kakoni @nhattan Maybe it is safer to write it as:

# user.rb
scope :with_any_roles, ->(names) do
  where(id: joins(:roles).select('users.id').distinct.where("roles.name IN (?)", names))
end

@Kani999
Copy link

Kani999 commented Jun 21, 2019

@milani - I'm using your code right now and it works like a charm.

Still waiting for this feature in a Gem

@martinstreicher
Copy link

It would be best if all role queries returned an AR, not an Array.

@NuclearMachine
Copy link

6 years 🥇

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.