开发者

Is it possible to validate that the title of a new post is not equal to an existing permalink?

开发者 https://www.devze.com 2023-01-04 20:00 出处:网络
In this simplified scenario, I have a model called Post Each post has a title and a permalink The permalink is used in the url - i.e. http://mysite.com/blog/permalink

In this simplified scenario, I have a model called Post

  • Each post has a title and a permalink

  • The permalink is used in the url - i.e. http://mysite.com/blog/permalink

  • Before a post is created, a callback sets the permalink to be the same as the title

I validate the uniqueness of each title but I do not explicitly validate the uniqueness of the permalink for three reasons:

  1. the permalink is equal to the title, which has already been validated for uniqueness
  2. users have no concept of the permalink, since they are never asked to enter one, so when they get an error telling them that the permalink needs to be unique, they don't have a clue what it means
  3. i'm using mongoid for the ORM and the permalink is the key for each post, and mongoid doesn't seem to let you modify a key

Now imagine the following scenario:

  • A user creates a post titled "hello" and the url is http://mysite.com/blog/hello

  • The user changes the title to "goodbye", but the permalink stays the same since it is immutable by design. This is fine, it's what I want and helps to prevents link-rot.

  • The user then creates a new post, titled "hello" which does not fail the validations since we changed the title of the first post already

The problem here is that we've now got two posts with t开发者_JAVA百科he same url thanks to our before_create callback.

As I said, I don't want to validate the uniqueness of the permalink as the user in the above scanrio, upon creating the second posts would receive the "permalink must be unique" error and I just know this will confuse them

So I was thinking, is there a validation, or a technique that allows me to prevent a user from creating a post which has a title that is equal to an existing permalink?

If all else fails, then I will just validate the uniqueness of the permalink and write out a really lengthy validation error message that details what the permalink is, and why this one is not deemed to be unique

The stuff we have to think about when making webites, what a carry-on


I can think of four possible solutions:

  1. Validate the uniqueness of permalink like this:

    validates_uniqueness_of :permalink, :message => "This title is already taken"
    

    This will present the user with an understandable message.

  2. change your before_create callback to create a numbered permalink

    def what_ever_your_callback_is_named
      self.permalink = self.title.permalinkify # or however you create the permalink
      while self.find_by_permalink(self.permalink)
        # check if it is an already numbered permalink
        if self.permalink =~ /^(.*)(-(\d+))?$/
          self.permalink = "#{$~[1]}-#{$~[3].to_i++}"
        else
          self.permalink << "-2"
        end
      end
    end
    
  3. change your before_create to a before_save callback, but than the resulting link is only permanent as long your title doesn't change.

  4. use friendly_id for creating and managing the permalink. It's very powerfull.


Your method that creates the permalink name could check whether that permalink is unique and if not then append a YYYYMMDDHHMMSS value (or some other value to create a unique permalink) to the permalink.


You can write a custom validation method

class Post < ActiveRecord::Base
   # You'll need to check only when creating a new post, right?
   def validate_on_create
      # Shows message if there's already a post with that permalink   
      if Post.first(:conditions => ["permalink = ?", self.title])
         errors.add_to_base "Your error message"
      end
   end
end
0

精彩评论

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