You are here: Forums Ask a Rails expert Validation of :id...
Posted in Forums : Ask a Rails expert
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. |
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? 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”? |
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.. |
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. |
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? |
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: |
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. |
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'
[...]
|
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 |
Authority 37
Posting Rating 100
Sign in to rate this post
|
Colin: |
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 ! |
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!). |
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?