Joel Blum
Joel Blum

Reputation: 7878

Rails Custom Validation With Request Params?

Rails noob ,

I am trying to write a custom validation but I am dependent on parameters that come from the post request. This example is similar to what I have - in this post model I want to validate that a user didn't already post on some topic, but to do that I have to have the topic id from the post request:

class Post < ActiveRecord::Base
...
   validate :user_already_posted, on: :create
   def user_already_posted
       topic=Topic.where(id: params[:topicId]).first
       //some code that runs on topic users and makes sure the user hasn't posted there

However , I learned that params isn't global and models can't access it (I last used laravel where this isn't the case , so it's confusing for me). Are custom validations not suited for what I need ? do I need to look at filters or have the controller run a validating function of it's own?

Upvotes: 1

Views: 1519

Answers (2)

MurifoX
MurifoX

Reputation: 15089

I think you are having a bit of a design problem here. You are creating a post validator, but the validation itself is not about the post instance. I mean, the model validator must evaluate all of the post attributes, using the default validators built-in ActiveRecord or creating custom ones, like you did, acessing the attributes via self.
I believe a class method receiving all your parameters and checking the conditions of the post creation is more clear:

Class method on the model

def self.user_already_posted(topic_id, user_id)
  # Do your thing
end

Usage on the controller

can_create = Post.user_already_posted(params[:topic_id], params[:user_id)

Upvotes: 0

NM Pennypacker
NM Pennypacker

Reputation: 6942

You could do this:

validates_uniqueness_of :user, scope: :topic_id

May not be exactly what you need, but the point is that you can validate within a scope. You can also pass an array to validate on multiple parameters.

validates_uniqueness_of :user, scope: [:topic_id, :post_id]

Upvotes: 1

Related Questions