# Model validation dependent upon session data being set?

**URL:** <https://discuss.rubyonrails.org/t/model-validation-dependent-upon-session-data-being-set/49747>\
**Category:** rubyonrails-talk\
**Created:** [February 27, 2010, 5:09pm UTC](https://discuss.rubyonrails.org/t/model-validation-dependent-upon-session-data-being-set/49747 "2010-02-27T17:09:42Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![Chase\_de\_Languillett](https://avatars.discourse-cdn.com/v4/letter/c/7ea924/32.png) [@Chase\_de\_Languillett](https://discuss.rubyonrails.org/u/Chase_de_Languillett)\
**Post date:** [February 27, 2010, 5:09pm UTC](https://discuss.rubyonrails.org/t/model-validation-dependent-upon-session-data-being-set/49747/1 "2010-02-27T17:09:42Z")

</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 &nbsp;&nbsp;has\_many :posts &nbsp;&nbsp;has\_and\_belongs\_to\_many :users (by way of a join table, a blog can have many contributing users)

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

User &nbsp;&nbsp;has\_and\_belongs\_to\_many :blogs (a user can contribute to many blogs) &nbsp;&nbsp;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 &nbsp;&nbsp;belongs\_to :blog &nbsp;&nbsp;belongs\_to :user &nbsp;&nbsp;has\_many :comments

&nbsp;&nbsp;validate :user\_can\_contribute

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

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

---

<div class="post-metadata">

**Author:** ![Chase\_de\_Languillett](https://avatars.discourse-cdn.com/v4/letter/c/7ea924/32.png) [@Chase\_de\_Languillett](https://discuss.rubyonrails.org/u/Chase_de_Languillett)\
**Post date:** [February 27, 2010, 5:12pm UTC](https://discuss.rubyonrails.org/t/model-validation-dependent-upon-session-data-being-set/49747/2 "2010-02-27T17:12:20Z")

</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:** ![Colin\_Law1](https://avatars.discourse-cdn.com/v4/letter/c/91b2a8/32.png) [@Colin\_Law1](https://discuss.rubyonrails.org/u/Colin_Law1)\
**Post date:** [February 27, 2010, 5:14pm UTC](https://discuss.rubyonrails.org/t/model-validation-dependent-upon-session-data-being-set/49747/3 "2010-02-27T17:14:32Z")

</div>

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:** ![Michael\_Pavling](https://avatars.discourse-cdn.com/v4/letter/m/8dc957/32.png) [@Michael\_Pavling](https://discuss.rubyonrails.org/u/Michael_Pavling)\
**Post date:** [February 27, 2010, 7:24pm UTC](https://discuss.rubyonrails.org/t/model-validation-dependent-upon-session-data-being-set/49747/4 "2010-02-27T19:24:39Z")

</div>

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 &nbsp;&nbsp;@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 &nbsp;&nbsp;@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

---

<div class="post-metadata">

**Author:** ![Michael\_Pavling](https://avatars.discourse-cdn.com/v4/letter/m/8dc957/32.png) [@Michael\_Pavling](https://discuss.rubyonrails.org/u/Michael_Pavling)\
**Post date:** [February 27, 2010, 7:36pm UTC](https://discuss.rubyonrails.org/t/model-validation-dependent-upon-session-data-being-set/49747/5 "2010-02-27T19:36:52Z")

</div>

\*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:** ![Chase\_de\_Languillett](https://avatars.discourse-cdn.com/v4/letter/c/7ea924/32.png) [@Chase\_de\_Languillett](https://discuss.rubyonrails.org/u/Chase_de_Languillett)\
**Post date:** [February 27, 2010, 11:14pm UTC](https://discuss.rubyonrails.org/t/model-validation-dependent-upon-session-data-being-set/49747/6 "2010-02-27T23:14:19Z")

</div>

Hey, that did the trick. Thanks for that!
