第一步:用bundle gem gem_name生成基本结构,如下:
- [root@arch demo]$ bundle gem rename_url
- create rename_url/Gemfile
- create rename_url/Rakefile
- create rename_url/.gitignore
- create rename_url/rename_url.gemspec
- create rename_url/lib/rename_url.rb
- create rename_url/lib/rename_url/version.rb
- Initializating git repo in /home/suchj/programs/demo/rename_url
注:
Gemfile # 描述依赖
Rakefile # 发布和打包的 rake tasks
GEM_NAME.gemspec # gem 的 spec
GEM_NAME/lib/GEM_NAME.rb 与 GEM_NAME/lib/GEMNAME/ # gem 里的 library
GEM_NAME/lib/GEM_NAME/version.rb # 版本记录
第二步:写Gems规范文件,rename_url.gemspec
- # -*- encoding: utf-8 -*-
- $:.push File.expand_path("../lib", __FILE__)
- require "rename_url/version"
- Gem::Specification.new do |s|
- s.name = "rename_url"
- s.version = RenameUrl::VERSION
- s.authors = ["xx"]
- s.email = ["xx@gmail.com"]
- s.homepage = ""
- s.summary = %q{TODO: Write a gem summary}
- s.description = %q{TODO: Write a gem description}
- s.rubyforge_project = "rename_url"
- s.files = `git ls-files`.split("\n")
- s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
- s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
- s.require_paths = ["lib"]
- # specify any dependencies here; for example:
- # s.add_development_dependency "rspec"
- # s.add_runtime_dependency "rest-client"
- end
第三步:写实现,lib/rename_url.rb
- require "rename_url/version"
- module RenameUrl
- def self.included(base)
- base.extend(ClassMethods)
- end
- module ClassMethods
- def urlize
- include RenameUrl::InstanceMethods
- end
- end
- module InstanceMethods
- def to_param
- "#{id}_#{title}"
- end
- end
- end
- ActiveRecord::Base.send(:include, RenameUrl) #在model中引入
第四步:打包gem
- [root@arch rename_url]$ gem build rename_url.gemspec
- WARNING: no homepage specified
- Successfully built RubyGem
- Name: rename_url
- Version: 0.0.1
- File: rename_url-0.0.1.gem
注:如果规范文件有信息没写全,会有警告
第五步:使用,在项目的Gemfile中加入
- gem 'rename_url', :path => '~/programs/rename_url'
注:gem文件在哪就写哪个路径
post.rb
- class Post < ActiveRecord::Base
- urlize #相当于include RenameUrl::InstanceMethods
- end
测试:
- [root@arch demo]$ rails c
- Loading development environment (Rails 3.0.4)
- 1.8.7 :001 > Post
- => Post(id: integer, name: string, title: string, content: text, created_at: datetime, updated_at: datetime)
- 1.8.7 :002 > Post.create(:title => "test")
- => #<Post id: 2, name: nil, title: "test", content: nil, created_at: "2012-02-03 08:38:53", updated_at: "2012-02-03 08:38:53">
- 1.8.7 :003 > Post.find_by_title("test").to_param
- => "2_test"
OK,打完收工