Sasha
Sasha

Reputation: 3281

rails, how to pass self in function

message and user. my message belongs_to user and user has_many messages.

in one of my views, i call something like

current_user.home_messages?

and in my user model, i have...

  def home_messages?
    Message.any_messages_for
  end

and lastly in my message model, i have

scope :any_messages_for

    def self.any_messages_for
        Message.where("to_id = ?", self.id).exists? 
    end

ive been trying to get the current_users id in my message model. i could pass in current_user as a parameter from my view on top but since im doing

current_user.home_messages?

i thought it would be better if i used self. but how do i go about referring to it correctly?

thank you.

Upvotes: 2

Views: 4688

Answers (3)

robotcookies
robotcookies

Reputation: 1059

You could use a lambda. In your Message model:

scope :any_messages_for, lambda {|user| where('user_id = ?', user.id)}

This would work like so:

Message.any_messages_for(current_user)

And you could add a method to your user model to return true if any messages are found. In this case you use an instance method and pass in the instance as self:

def home_messages?
  return true if Message.any_messages_for(self)
end

But really, I'd just do something like this in the User model without having to write any of the above. This uses a Rails method that is created when declaring :has_many and :belongs_to associations:

def home_messages?
  return true if self.messages.any?
end

Upvotes: 7

mu is too short
mu is too short

Reputation: 434685

This stuff in your Message class doesn't make a lot of sense:

scope :any_messages_for

def self.any_messages_for
    Message.where("to_id = ?", self.id).exists? 
end

The scope macro defines a class method on its own and there should be another argument to it as well; also, scopes are meant to define, more or less, a canned set of query parameters so your any_messages_for method isn't very scopeish; I think you should get rid of scope :any_messages_for.

In your any_messages_for class method, self will be the class itself so self.id won't be a user ID and so it won't be useful as a placeholder value in your where.

You should have something more like this in Message:

def self.any_messages_for(user)
  where('to_id = ?', user.id).exists?
  # or exists?(:to_id => user.id)
end

And then in User:

def home_messages? Message.any_messages_for(self) end

Once all that's sorted out, you can say current_user.home_messages?.

Upvotes: 1

Salil
Salil

Reputation: 47482

You can do either of the following

def self.any_messages_for(id) #This is a class method
    Message.where("to_id = ?", id).exists? 
end

to call above method you have to do

User.any_messages_for(current_user.id) #I am assuming any_messages_for is in `User` Model

OR

def any_messages_for #This is a instance method
    Message.where("to_id = ?", self.id).exists? 
end

to call above method you have to do

current_user.any_messages_for

Upvotes: 2

Related Questions