Rails scope find with current user
If you're running this code in a lot of your controllers, you should probably make it a before filter, and define a method to do that in your ApplicationController:
before_filter :set_product, :except => [:destroy, :index]
def set_product
@product = current_user.admin? ? Product.find(params[:id]) : current_user.products.find(params[:id])
end
I don't know what you use to determine if a user is an admin or not (roles), but if you look into CanCan, it has an accessible_by
scope that accepts an ability (an object that controls what users can and can't do) and returns records that user has access to based on permissions you write yourself. That is probably really what you want, but ripping out your permissions system and replacing it may or may not be feasible for you.
Ruby on Rails scope test for current user
You can't do this, nor should you. There is no "current" user at the database level.
You need to pass the user object in to a class-level method:
def self.open_for_user(user)
where(:contact_id => user.id)
end
How to create a scope for current_user.following?
There are 2 things you may approach:
Find all users who are following someone
class User < ActiveRecord::Base
scope :following_to, -> (user_id) {
where(
"id IN ( SELECT followed_id
FROM relationships
WHERE follower_id = ?
)",
user_id
)
}
endFind all users who are following anyone, that means they are a follower
class User < ActiveRecord::Base
scope :follower, -> {
where("id IN ( SELECT followed_id FROM relationships)")
}
end
Finally, you can use these scope as your expectation:
# Find all users who are following to User (id = 1)
User.following_to(1)
# Find all users who are following someone,
# aka they are a follower
User.follower
default_scope for current_user
I'm not sure why you want to do this at all. The best approach is to use the controller to scope your models. This type of thing doesn't belong to the model.
def index
@albums = current_user.albums
end
If you want to avoid the repetition, create methods to retrieve the object. So instead of this:
def show
@album = current_user.albums.find(params[:id])
end
def edit
@album = current_user.albums.find(params[:id])
end
# etc...
You can do this:
def index
albums
end
def show
album
end
def update
if album.update(album_params)
end
# etc...
private
def albums
@albums ||= current_user.albums
end
def album
@album ||= current_user.albums.find(params[:id)
end
You can even avoid calling the album method from the action by using a before_filter
, but this is not a good way. You always tend to forget to add and remove actions from the filter.
before_action :set_album, only: [:show, :edit, :update, :destroy]
def set_album
@album ||= current_user.albums.find(params[:id])
end
Then your instance variables are created in one place. As @wacaw suggested, if this appeals to you, you can take it further and use the decent_exposure gem. Personally, I am happy to stop at the controller and use instance methods in my views.
If you have more complex authorisation needs I suggest you use pundit or cancan, although the latter does not appear to be actively maintained.
There is more on decent_exposure on Rails Casts. If you really fancy this type of scoping, look at this Rails Cast on Multitenancy with Scopes. But that is meant for organisations that have many of users, not a single user.
.current_user not working when using scopes?
One solution is to create a scope in the link that takes an argument user_id and in your controller has_scope with no arguments, and just pass a hash to apply_scopes method to override the supplied values of your scope.
Link Model
scope :of_user,->(user_id){ where(user_id: user_id)}
Link Controller
has_scope :of_user
Just call apply_scopes(Link, of_user: current_user.id).all where of_user is just the applied params for the named scope.
search records by user in the scope
No, you can not call current_user
in model. This helper is only available in controllers/views.
You can change the scope to accept an argument:
scope :por_empresa, ->(user) { where(IdEmpresa: user.empresa_id) }
Now you can use it in controller as follows (passing the current_user
object as an argument to scope):
Model.por_empresa(current_user)
Of course you can optimize it a bit by passing only user's id
:
scope :por_empresa, ->(user_id) { where(IdEmpresa: user_id) } # model
Model.por_empresa(current_user.id) # usage
P.S. it looks like a bad practice to me having non-english words in your code base..
RoR Filter Out Current User with Join, Select and Order
This should do the trick:
@users = ...
@users = @users.where.not(users: {id: current_user.id})
Note that you need to specify name of the table (not the model) when you do the join, otherwise database will have no idea which id column it should look for (users.id
vs departments.id
).
Before Rails 4
not
method is quite a new thing and is not available in Rails 3. (In fact, where method wasn't expecting to be called without arguments, that's why the error you got is unexpected number of arguments (0 for 1)
).
Those were dark times when we had to use the following monstrosity to get stuff working:
@users = ...
@users = @users.where('users.id != ?', current_user.id)
Rails ActiveRecord: Find All Users Except Current User
It is possible to do the following in Rails 4 and up:
User.where.not(id: id)
You can wrap it in a nice scope.
scope :all_except, ->(user) { where.not(id: user) }
@users = User.all_except(current_user)
Or use a class method if you prefer:
def self.all_except(user)
where.not(id: user)
end
Both methods will return an AR relation object. This means you can chain method calls:
@users = User.all_except(current_user).paginate
You can exclude any number of users because where()
also accepts an array.
@users = User.all_except([1,2,3])
For example:
@users = User.all_except(User.unverified)
And even through other associations:
class Post < ActiveRecord::Base
has_many :comments
has_many :commenters, -> { uniq }, through: :comments
end
@commenters = @post.commenters.all_except(@post.author)
See where.not()
in the API Docs.
Related Topics
Can Not Install JSON Gem with Ruby 2.2.3 on Ubuntu
Does Scala Scale Better Than Other Jvm Languages
How to Handle Exceptions with Ruby Rest-Client
How to Use an Overridden Constant in an Inheritanced Class
Running Ruby Unit Tests with Rake
How to Override Static Class Method Using Module in Ruby
Key Issue with Installing Rvm (Ruby Version Manager)
Spinach VS Cucumber for Bdd in Rails
Ruby: Put Request with JSON Body
How to Generate the First N Prime Numbers
Rails 4 Migration: Has_And_Belongs_To_Many Table Name
Bundle Command Not Found in Linux Debian
Mapping Values from Two Array in Ruby
How to Inspect the Methods of a Ruby Object