开发者

Rails updating attribute security: use a callback or attr_accessible?

I've got a website model that requires a user to verify ownership of the website.

Thanks to stack overflow, I was able to find the solution for user ownership verification here: Validate website ownership in rails

After the model passes the verification test there is a verified attribute that gets set to true.

The problem I'm running into is when the user wants to edit attributes of his or her website, he or she could easily change the name of the domain while the verified attribute remains true, thus allowing the user to create website objects without verifying ownership.

I can think of two ways to solve this: 1. Have a callback that changes the veri开发者_Go百科fication to false if the domain name of the website gets changed. 2. Allow attr_accessible for the domain upon the creation of a new object but not when updating it.

I'm stumped as to how to implement either of these practically.


Callbacks and Active Record Dirty methods are definitely the way to go for this type of situation.

before_update :set_domain_status

def set_domain_status
  self.verified = false if self.domain_changed?      
end

_changed? can be added to any attribute, returning true if the value has changed from that originally loaded from the database.


I think your Option#1 is the best route. Otherwise you get into the business of trying to reconcile create and update actions - which you would need to do to handle Option #2.

You could override the setter for domain name and then perform custom logic, like so:

In your Model:

def domain=(the_domain)
 raise ValidOwnerRequired if verified? && domain != the_domain
 # if we got here then the this record is new and this is a creation attempt
 @require_domain_verification = true 
 # do other stuff here..
end

def require_domain_verification?
  @require_domain_verification == true
end

And then have an observer for that model:

def after_save(record)
  if record.require_domain_verification?
    SomeMailer.deliver_domain_verification(record)
  end
end

Something like that...


Cody, your answer got me on the right track. Thanks a lot!

This is what I went for in my case:

  def domain=(the_domain)
     if domain != the_domain
     self[:domain] = the_domain
     self[:verified] = false
    end
  end

It works just fine.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜