Permalink
Browse files

Initial implementation.

  • Loading branch information...
1 parent a864238 commit a46fe08385c742026da17e14e38968b2ba3ee7c7 @pk committed Nov 17, 2009
Showing with 122 additions and 9 deletions.
  1. +1 −1 LICENSE
  2. +1 −1 README.rdoc
  3. +4 −4 Rakefile
  4. +66 −0 lib/sequel_sluggable.rb
  5. +7 −0 lib/version.rb
  6. +32 −2 spec/sequel_sluggable_spec.rb
  7. +11 −1 spec/spec_helper.rb
View
@@ -1,4 +1,4 @@
-Copyright (c) 2009 Pavel
+Copyright (c) 2009 Pavel Kunc
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
View
@@ -15,4 +15,4 @@ Description goes here.
== Copyright
-Copyright (c) 2009 Pavel. See LICENSE for details.
+Copyright (c) 2009 Pavel Kunc. See LICENSE for details.
View
@@ -5,14 +5,14 @@ begin
require 'jeweler'
Jeweler::Tasks.new do |gem|
gem.name = "sequel_sluggable"
- gem.summary = %Q{TODO: one-line summary of your gem}
- gem.description = %Q{Sequel}
+ gem.summary = %Q{Sequel plugin which provides Slug for model.}
+ gem.description = %Q{TODO}
gem.email = "pavel.kunc@gmail.com"
gem.homepage = "http://github.com/pk/sequel_sluggable"
- gem.authors = ["Pavel"]
+ gem.authors = ["Pavel Kunc"]
+ gem.add_dependency "sequel", ">= 3.0.0"
gem.add_development_dependency "rspec", ">= 1.2.9"
gem.add_development_dependency "yard", ">= 0"
- # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
end
rescue LoadError
puts "Jeweler (or a dependency) not available. Install it with: sudo gem install jeweler"
View
@@ -0,0 +1,66 @@
+module Sequel
+ module Plugins
+ # The Sluggable plugin creates hook that automatically sets 'slug' field to
+ # the slugged value of the column specified by :source option.
+ #
+ # You need to have "slug" column in your model.
+ #
+ module Sluggable
+ # Set the source column for the model.
+ # Options:
+ # * :source - The column to get value to be slugged from.
+ def self.configure(model, opts={})
+ model.slug_source_column = opts[:source]
+ end
+
+ module ClassMethods
+ attr_accessor :slug_source_column
+
+ # Finds model by slug or id
+ #
+ # ==== Returns
+ # PhotoGallery
+ def find_by_id_or_slug(value)
+ filter = value.to_s =~ /^\d+$/ ? {:id => value} : {:slug => value.chomp}
+ self[filter]
+ end
+ end
+
+ module InstanceMethods
+
+ # Sets slug column to the slugged value
+ def before_save
+ super
+ self.slug = self.send(self.class.slug_source_column)
+ end
+
+ private
+
+ # Sets the slug to the normalized URL friendly string
+ #
+ # Compute slug for the value
+ #
+ # ==== Parameters
+ # v<String>:: String to be slugged
+ #
+ # ==== Returns
+ # String:: Slug
+ def slug=(v)
+ super(to_slug(v))
+ end
+
+ # Generate slug from the passed value
+ #
+ # ==== Parameters
+ # v<String>:: String to be slugged
+ #
+ # ==== Returns
+ # String:: Slug
+ def to_slug(v)
+ v.chomp.downcase.gsub(/[^a-z0-9]+/,'-')
+ end
+
+ end # InstanceMethods
+ end # Sluggable
+ end # Plugins
+end # Sequel
View
@@ -0,0 +1,7 @@
+module Sequel
+ module Plugins
+ module Sluggable
+ VERSION = '0.0.1'.freeze
+ end
+ end
+end
@@ -1,7 +1,37 @@
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
+class Item < Sequel::Model; end
+
describe "SequelSluggable" do
- it "fails" do
- fail "hey buddy, you should probably rename this file and start specing for real"
+ before(:each) do
+ Item.plugin :sluggable, :source => :name
+ end
+
+ it "should be loaded using Model.plugin" do
+ Item.plugins.should include(Sequel::Plugins::Sluggable)
+ end
+
+ it "should add find_by_id_or_slug" do
+ Item.should respond_to(:find_by_id_or_slug)
+ end
+
+ it "should accept extra options" do
+ Item.slug_source_column.should eql :name
+ end
+
+ it "should generate slug when saved" do
+ Item.create(:name => 'Pavel Kunc').slug.should eql 'pavel-kunc'
+ end
+
+ describe "::find_by_id_or_slug" do
+ it "should find model by slug" do
+ item = Item.create(:name => 'Pavel Kunc')
+ Item.find_by_id_or_slug('pavel-kunc').should eql item
+ end
+
+ it "should find model by id" do
+ item = Item.create(:name => 'Pavel Kunc')
+ Item.find_by_id_or_slug(item.id).should eql item
+ end
end
end
View
@@ -1,9 +1,19 @@
$LOAD_PATH.unshift(File.dirname(__FILE__))
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
+require 'sequel'
require 'sequel_sluggable'
require 'spec'
require 'spec/autorun'
+DB = Sequel.sqlite
+DB.create_table :items do
+ primary_key :id
+ String :name
+ String :slug
+end
+
+class Item < Sequel::Model; end
+
Spec::Runner.configure do |config|
-
+ config.after(:each) { Item.delete }
end

0 comments on commit a46fe08

Please sign in to comment.