Spyros
Spyros

Reputation: 105

Rails - Custom Validation that requires current_user information

I'm having a very difficult rails problem and i thought to ask for some help. The situation is like this :

I'm using restful authentication for my User model. Now, user has a field named 'gold' that is a numeric value. There is another model named Book that has been created using scaffolding.

What i want to do is simple, yet i cannot see a way of doing it. I want to add some validation where if the user's gold is not, let's say 100, they cannot create a new book entry(from the scaffolding standard view).

Now the problem is that i need current_user information in order to validate this from my model. I need that in order to get the user id and therefore get their gold amount as well. I cannot find a good way (if any) to do that.

Another thought was doing that from a controller. However, the standard "if @book.save" block does not really allow me to insert my own error messages (inside scaffold create) :

if not User.has_the_needed_gold(current_user, 100)
  flash[:goldError] = 'You do not have the needed gold to create this book.'
#end


respond_to do |format|
  if @book.save
    flash[:notice] = 'Book was successfully created.'
    format.html { redirect_to(@book) }
    format.xml  { render :xml => @book, :status => :created, :location => @book }
  else
    format.html { render :action => "new" }
    format.xml  { render :xml => @book.errors, :status => :unprocessable_entity }
  end
end

Now, i cannot output that message and abort the save of the new book as well. I've tried adding my own error to base, but it was cleared out(after save i guess). I'm quite confused with the situation and i've been searching around for a couple of hours with no results.

If anybody can help with that, please do so, you would spare me lots of trouble :)

Thanx for reading !

Upvotes: 2

Views: 2113

Answers (2)

monocle
monocle

Reputation: 5896

You could define a :user_gold virtual attribute for Book, set it in the controller where you have access to current_user and then incorporate that into your Book validation.

Upvotes: 3

Josiah Kiehl
Josiah Kiehl

Reputation: 3633

Look the user up when validating. It's likely the user lookup will have been cached by ActiveRecord, so it's not a performance hit to do so. Try something like this:

class Book

  validate :check_gold

  def check_gold
    user = User.find(self.user_id)
    self.errors.add(:user_id => "#{user.name} doesn't have enough gold!") if user.nil? or (user.gold < 100)
  end
end

Upvotes: 2

Related Questions