Browse the Ruby on Rails Community.

You are here: Forums Ask a Rails expert Validation of :id...

Replytotopic

Validation of :id

Posted in Forums : Ask a Rails expert

 
Profile

Authority 12
Posting Rating 0
Sign in to rate this post

Hi I’m a newbie,

I’m have a control record in the database, it has an id of 0, users should never be able to edit or delete this record, so I have a helper in the controller

validates_numericality_of :id, :on => {:destroy,:update}, :greater_than => 0

I get an error of nil is not a symbol

Does this mean you can’t validate the id attribute, or have I made a big mistake, or is there a better way – any help appreciated.

 
Me

Authority 37
Posting Rating 100
Sign in to rate this post

Let me guess – you only get the error when you create a new record?
id is the primary key and it doesn’t exist when this validation runs. Moreover, why would you need to validate the id? Can the users of your app set the id themselves? If yes, you should definitely change that because the primary key should NEVER be modified!

If you definitely need to do it the way you do (again – I think you’re doing something wrongly if you need to do it) you could always write some kind of safe find method like this:

class MyClass extends ActiveRecord::Base
  def self.safe_find(id)
    raise RecordNotFound, "Couldn't find #{name} without an ID" if id.to_i == 0 # throws an exception like the regular find would
    self.find(id)
  end
end

This raises an error if the id is 0 and otherwise calls the usual find. In your controllers, you can just replace all your normal finds with safe_find so the record can never be displayed, updated or destroyed.

PS: Out of mere curiosity: What do you mean by “control record”?

 
Profile

Authority 12
Posting Rating 0
Sign in to rate this post

Hi thanks for that, i don’t get the error only on new.

If I go to the console and try

controlrecord.find(1) I still get the error

The reason I have this record as 0 is because its not used anywhere in the database, and I can easily modify the find kinda like you described above. so it does not show up in a find(:all). But as belt and braces I don’t want the record deleted. Hence..

 
Profile

System Admin
Sign in to rate this post

How about a filter on the model? A before_save filter which returns false if the ID is 0 should stop anyone modifying the record with id = 0. Much cleaner.

 
Me

Authority 37
Posting Rating 100
Sign in to rate this post

David: Good idea but technically that’s not what you’d expect of the app, I guess. If the user accesses a record that (again, technically) isn’t there, I’d expect a 404 which, after all, is exactly what happens if you raise a RecordNotFound exception.

That being said, I still don’t see why a record with pk = 0 should be in the database … Couldn’t you refactor that in a config file?

 
Me

Authority 75
Posting Rating 0
Sign in to rate this post

I haven’t really read much of this, but isn’t validates_numericality_of :id, :on => {:destroy,:update}, :greater_than => 0 supposed to be:
validates_numericality_of :id, :on => [:destroy, :update], :greater_than => 0
?

 
Profile

System Admin
Sign in to rate this post

Clemens, I think you’ve misinterpreted what Colin is trying to do – or at least what I think he is trying to do!

He is saying that he has record, with ID=0, that he doesn’t want the user to be able to alter, no matter what. So refusing to edit a model/record with ID=0 is, by definition, what he wants, right? There is no issue of the record “technically not being there” – it IS there, he just doesn’t want anyone to be able to edit or delete it. Your safe_find method would stop him ever even loading the record with ID=0, which isn’t what he wants.

 
Profile

Authority 12
Posting Rating 91
Sign in to rate this post
 class MyModel < ActiveRecord::Base
    before_destroy :protect_record_0
    before_save :protect_record_0

    private
      def protect_record_0
        raise 'trying to modify record with id==0 !!!' if self.id == 0
      end
  end

quick sample from some of my models:

>> c = Country.find_by_name('Marcin')
=> #<Country id: 0, name: "Marcin", code: "mb", lock_version: 0>
>> c.destroy
RuntimeError: trying to modify record with id==0 !!!
        from D:/rails_proj/cv/cv2.0/app/models/country.rb:10:in `protect_record_0'
        from c:/ruby/lib/ruby/gems/1.8/gems/activerecord-2.0.2/lib/active_record/callbacks.rb:307:in `send'

[...]

>> c.update_attribute(:name, 'aaa')
RuntimeError: trying to modify record with id==0 !!!
        from D:/rails_proj/cv/cv2.0/app/models/country.rb:10:in `protect_record_0'
        from c:/ruby/lib/ruby/gems/1.8/gems/activerecord-2.0.2/lib/active_record/callbacks.rb:307:in `send'
[...]
 
Profile

Authority 12
Posting Rating 0
Sign in to rate this post

Hi, Thanks for all the input.

i do need to be able to see the record in a collection, so the safe find method doesn’t work for me.

I’ve gone with Marcins method. I’m very interested to know why my original method doesn’t work. I’ve tried replacing the { with [ but it still doesn’t work

 
Me

Authority 37
Posting Rating 100
Sign in to rate this post

Colin:
I’m not sure why it doesn’t work for the update but the reason for not working with destroy is quite simple: There is no validation on destroy!

 
Profile

Authority 12
Posting Rating 0
Sign in to rate this post

Clemens – thats it

if you change it to

validates_numericality_of :id, :on => :update, :greater_than => 0

then it works in the console.

Surely though there should be some method of validating in the destroy method – or am i totally out of date !

 
Me

Authority 37
Posting Rating 100
Sign in to rate this post

No, there is no validation for destroy because it wouldn’t make sense! Validations in ActiveRecord are meant to validate user input – destroy doesn’t take any user input (i.e. there is nothing to update or create) so there is no validation (and there never was, before you ask!).

Replytotopic

Other Recent Topics

Ask a Rails expert : how to write in model

Ask a Rails expert : how to show the params value in page.alert

Ask a Rails expert : Cutomize Will_Paginate next & previouse links

Ask a Rails expert : support AJAX pagination with Will_Paginate plug-in

Ask a Rails expert : Inheritance Determination in View

Ask a Rails expert : Install rails application

Ask a Rails expert : custom sql query

Ask a Rails expert : session handling does not work with REST API

Ask a Rails expert : Display WSDL

Ask a Rails expert : Howto respond a XML error message when there is no @active_record_obj?

Formatting Help
  • *bold*       _italics_      
    bq. (quotes)
  • "DSC":http://www.dsc.net
  • * or # (lists)
or cancel