Guest User

Untitled

a guest
Feb 20th, 2018
85
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.44 KB | None | 0 0
  1. module LuckySneaks
  2. module ActsAsUrl # :nodoc:
  3. def self.included(base)
  4. base.extend ClassMethods
  5. end
  6.  
  7. module ClassMethods # :doc:
  8. # Creates a callback to automatically create an url-friendly representation
  9. # of the <tt>attribute</tt> argument. Example:
  10. #
  11. # act_as_url :title
  12. #
  13. # will use the string contents of the <tt>title</tt> attribute
  14. # to create the permalink. You may also pass a Proc object instead and this
  15. # object will be evaluated and its return value used instead of a database
  16. # attribute
  17. #
  18. # The default attribute <tt>acts_as_url</tt> uses
  19. # to store the permalink on the database is <tt>url</tt> but can be changed in the options hash.
  20. # Available options are:
  21. #
  22. # <tt>:url_attribute</tt>:: The name of the attribute to use for storing the generated url string.
  23. # Default is <tt>:url</tt>
  24. # <tt>:scope</tt>:: The name of model attribute to scope unique urls to. There is no default here.
  25. # <tt>:sync_url</tt>:: If set to true, the url field will be updated when changes are made to the
  26. # attribute it is based on. Default is false.
  27. def acts_as_url(attribute, options = {})
  28. cattr_accessor :attribute_to_urlify
  29. cattr_accessor :scope_for_url
  30. cattr_accessor :url_attribute # The attribute on the DB
  31.  
  32. if options[:sync_url]
  33. before_validation :ensure_unique_url
  34. else
  35. before_validation_on_create :ensure_unique_url
  36. end
  37.  
  38. self.attribute_to_urlify = attribute
  39. self.scope_for_url = options[:scope]
  40. self.url_attribute = options[:url_attribute] || "url"
  41. end
  42.  
  43. # Initialize the url fields for the records that need it. Designed for people who add
  44. # <tt>acts_as_url</tt> support once there's already development/production data they'd
  45. # like to keep around.
  46. #
  47. # Note: This method can get very expensive, very fast. If you're planning on using this
  48. # on a large selection, you will get much better results writing your own version with
  49. # using pagination.
  50. def initialize_urls
  51. find(:all, :conditions => {self.url_attribute => nil}).each do |instance|
  52. instance.send :ensure_unique_url
  53. instance.save
  54. end
  55. end
  56. end
  57.  
  58. private
  59. def ensure_unique_url
  60. url_attribute = self.class.url_attribute
  61. base_url = get_base_url
  62. conditions = ["#{url_attribute} = ?", base_url]
  63. unless new_record?
  64. conditions.first << " and id != ?"
  65. conditions << id
  66. end
  67. if self.class.scope_for_url
  68. conditions.first << " and #{self.class.scope_for_url} = ?"
  69. conditions << send(self.class.scope_for_url)
  70. end
  71. url_owners = self.class.find(:all, :conditions => conditions)
  72. if url_owners.size > 0
  73. n = 1
  74. while url_owners.detect{|u| u.send(url_attribute) == "#{base_url}-#{n}"}
  75. n = n.succ
  76. end
  77. write_attribute url_attribute, "#{base_url}-#{n}"
  78. else
  79. write_attribute url_attribute, base_url
  80. end
  81. end
  82.  
  83. def get_base_url
  84. if self.class.attribute_to_urlify.is_a?(Proc)
  85. instance_exec self, &self.class.attribute_to_urlify
  86. else
  87. send self.class.attribute_to_urlify
  88. end.to_s.to_url
  89. end
  90. end
  91. end
Add Comment
Please, Sign In to add comment