# Model validation dependent upon session data being set?

**URL:** <https://www.ruby-forum.com/t/model-validation-dependent-upon-session-data-being-set/184267>\
**Category:** Rails\
**Created:** [February 27, 2010, 6:10pm UTC](https://www.ruby-forum.com/t/model-validation-dependent-upon-session-data-being-set/184267 "2010-02-27T18:10:58Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![robo](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/bb73d2/32.png) [@robo](https://www.ruby-forum.com/u/robo)\
**Post date:** [February 27, 2010, 6:10pm UTC](https://www.ruby-forum.com/t/model-validation-dependent-upon-session-data-being-set/184267/1 "2010-02-27T18:10:58Z")

</div>

Ok so I have a few models that need to interact with each other -  
Blog, Post, and User. I’ll get their relationships out of the way:

Blog  
has\_many :posts  
has\_and\_belongs\_to\_many :users (by way of a join table, a blog can  
have many contributing users)

Post  
belongs\_to :blog  
belongs\_to :user (the author of the post)

User  
has\_and\_belongs\_to\_many :blogs (a user can contribute to many blogs)  
has\_many :posts

I’m running into a problem when validating posts; I want to ensure  
that the logged in user we find in the session is listed as a  
contributor to the blog they are trying to post to. I added some  
validation to my Post model, that appears to be failing when editing  
an existing post. Post creation, curiously, seems to pass the  
validation test.

I should note that @user is a variable set by my ApplicationController  
using a before\_filter. really sure what’s going on here, so any help  
is appreciated. I’m guessing the @user set by my app controller  
probably isn’t accessible by the Post class.

Anyhow, here’s my Post model:

class Post \< ActiveRecord::Base  
belongs\_to :blog  
belongs\_to :user  
has\_many :comments

validate :user\_can\_contribute

private  
def user\_can\_contribute  
if @user.nil?  
logger.info("@user hasn’t been set yet!")  
end

```
if !blog.users.include?(@user)
  errors.add(:user, "You cannot contribute to this blog.")
end

```

end  
end

---

<div class="post-metadata">

**Author:** ![robo](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/bb73d2/32.png) [@robo](https://www.ruby-forum.com/u/robo)\
**Post date:** [February 27, 2010, 6:13pm UTC](https://www.ruby-forum.com/t/model-validation-dependent-upon-session-data-being-set/184267/2 "2010-02-27T18:13:53Z")

</div>

Actually, I’m not so sure if post creation is passing the validation  
test either 🙂

Sorry for being confusing.

---

<div class="post-metadata">

**Author:** ![robo](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/bb73d2/32.png) [@robo](https://www.ruby-forum.com/u/robo)\
**Post date:** [February 27, 2010, 6:16pm UTC](https://www.ruby-forum.com/t/model-validation-dependent-upon-session-data-being-set/184267/3 "2010-02-27T18:16:14Z")

</div>

On 27 February 2010 17:09, robo [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> belongs\_to :user (the author of the post)  
> an existing post. Post creation, curiously, seems to pass the  
> belongs\_to :blog
> 
> if !blog.users.include?(@user)  
> errors.add(:user, “You cannot contribute to this blog.”)  
> end  
> end  
> end

Have you tried using ruby-debug to break into the validation code and  
see what is happening? See the rails guide on debugging at

> **[Ruby on Rails Guides](https://guides.rubyonrails.org/)**
>
> Ruby on Rails Guides

Colin

---

<div class="post-metadata">

**Author:** ![robo](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/bb73d2/32.png) [@robo](https://www.ruby-forum.com/u/robo)\
**Post date:** [February 27, 2010, 8:39pm UTC](https://www.ruby-forum.com/t/model-validation-dependent-upon-session-data-being-set/184267/4 "2010-02-27T20:39:02Z")

</div>

On 27 February 2010 19:24, Michael P. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> So you need to create a method on your controller that will return the  
> @user object. The convention for this method seems to be to call it  
> “current\_user”.

_ahem_ Of course… an instance of a model doesn’t have access to  
application\_controller’s methods… I was getting carried away with  
myself.  
You will _also_ need to pass this to the Post directly… so declare  
an “attr\_writer :current\_user” on your Post model, and in the  
controller, when you instanciate the Post, pass it the variable:

post = Post.find(params[:post\_id] # or whatever…  
post.current\_user = current\_user

---

<div class="post-metadata">

**Author:** ![robo](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/bb73d2/32.png) [@robo](https://www.ruby-forum.com/u/robo)\
**Post date:** [February 28, 2010, 12:15am UTC](https://www.ruby-forum.com/t/model-validation-dependent-upon-session-data-being-set/184267/5 "2010-02-28T00:15:32Z")

</div>

Hey, that did the trick. Thanks for that!

---

<div class="post-metadata">

**Author:** ![robo](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/bb73d2/32.png) [@robo](https://www.ruby-forum.com/u/robo)\
**Post date:** [February 27, 2010, 8:26pm UTC](https://www.ruby-forum.com/t/model-validation-dependent-upon-session-data-being-set/184267/6 "2010-02-27T20:26:10Z")

</div>

On 27 February 2010 17:09, robo [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> I should note that @user is a variable set by my ApplicationController  
> using a before\_filter. really sure what’s going on here, so any help  
> is appreciated. I’m guessing the @user set by my app controller  
> probably isn’t accessible by the Post class.

Yup - you’ve identified your problem perfectly… here’s a suggested  
solution:

@user is a instance variable; that is, only available to the instance  
of a class (in this instance, the controller). So you can’t access it  
from an instance of a different class.  
So you need to create a method on your controller that will return the  
@user object. The convention for this method seems to be to call it  
“current\_user”.

def current\_user  
@user  
end

Simple, huh? 😉  
Now you can get rid of that before\_filter call, and do the operation  
when/if somewhere calls “current\_user” - so it’ll look more like this:

def current\_user  
@user ||= the\_method\_for\_the\_logic\_that\_works\_out\_the\_logged\_in\_user  
end

An other solution would be to use a wrapped-up plugin to do  
authentication (there are lots to choose from), which would take all  
you user/password management woes and deal with them for you (and most  
likely give you a “current\_user” method!)

HTH  
Michael
