├── .gitignore ├── .rspec ├── .ruby-gemset ├── .ruby-version ├── Gemfile ├── LICENSE.txt ├── README.md ├── Rakefile ├── activerecord-postgresql-citext.gemspec ├── lib └── activerecord │ └── postgresql │ └── citext.rb └── spec ├── citext_spec.rb └── spec_helper.rb /.gitignore: -------------------------------------------------------------------------------- 1 | *.gem 2 | *.rbc 3 | .bundle 4 | .config 5 | .yardoc 6 | Gemfile.lock 7 | InstalledFiles 8 | _yardoc 9 | coverage 10 | doc/ 11 | lib/bundler/man 12 | pkg 13 | rdoc 14 | spec/reports 15 | test/tmp 16 | test/version_tmp 17 | tmp 18 | -------------------------------------------------------------------------------- /.rspec: -------------------------------------------------------------------------------- 1 | --color 2 | --format progress 3 | -------------------------------------------------------------------------------- /.ruby-gemset: -------------------------------------------------------------------------------- 1 | activerecord-postgres-citext 2 | -------------------------------------------------------------------------------- /.ruby-version: -------------------------------------------------------------------------------- 1 | ruby-1.9.3-p194 2 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | source 'https://rubygems.org' 2 | 3 | # Specify your gem's dependencies in activerecord-postgres-citext.gemspec 4 | gemspec 5 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2013 Braintree 2 | 3 | MIT License 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining 6 | a copy of this software and associated documentation files (the 7 | "Software"), to deal in the Software without restriction, including 8 | without limitation the rights to use, copy, modify, merge, publish, 9 | distribute, sublicense, and/or sell copies of the Software, and to 10 | permit persons to whom the Software is furnished to do so, subject to 11 | the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be 14 | included in all copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 19 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 20 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 21 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 22 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ActiveRecord support for citext 2 | 3 | Adds support for citext to active_record 4 | 5 | ## Installation 6 | 7 | Add this line to your application's Gemfile: 8 | 9 | gem 'activerecord-postgresql-citext' 10 | 11 | And then execute: 12 | 13 | $ bundle 14 | 15 | Or install it yourself as: 16 | 17 | $ gem install activerecord-postgresql-citext 18 | 19 | ## Usage 20 | 21 | In a database migration you need to first enable `citext` as an extension, then you can create columns of type citext. 22 | 23 | ```ruby 24 | def up 25 | enable_extension("citext") 26 | 27 | create_table :models, :force => true do |t| 28 | t.citext :name 29 | t.timestamps 30 | end 31 | end 32 | ``` 33 | 34 | ## Contributing 35 | 36 | 1. Fork it 37 | 2. Create your feature branch (`git checkout -b my-new-feature`) 38 | 3. Commit your changes (`git commit -am 'Add some feature'`) 39 | 4. Push to the branch (`git push origin my-new-feature`) 40 | 5. Create new Pull Request 41 | -------------------------------------------------------------------------------- /Rakefile: -------------------------------------------------------------------------------- 1 | require "rspec/core/rake_task" 2 | require "active_record" 3 | 4 | RSpec::Core::RakeTask.new(:spec) 5 | 6 | task :default => %w(db:do_over spec) 7 | 8 | namespace :db do 9 | task :create do 10 | connection.execute "CREATE DATABASE activerecord_postgresql_citext" 11 | end 12 | 13 | task :drop do 14 | connection.execute "DROP DATABASE IF EXISTS activerecord_postgresql_citext" 15 | end 16 | 17 | def connection 18 | config = { 19 | :adapter => 'postgresql', 20 | :template => 'template0', 21 | :schema_search_path => 'public', 22 | :username => ENV["DB_USERNAME"] || ENV["USER"], 23 | :password => ENV["DB_PASSWORD"], 24 | :host => 'localhost', 25 | :port => ENV["DB_PORT"] || 5433 26 | } 27 | ActiveRecord::Base.establish_connection(config.merge('database' => 'postgres', 'schema_search_path' => 'public')) 28 | ActiveRecord::Base.connection 29 | end 30 | 31 | task :do_over => %w(drop create) 32 | end 33 | -------------------------------------------------------------------------------- /activerecord-postgresql-citext.gemspec: -------------------------------------------------------------------------------- 1 | # coding: utf-8 2 | lib = File.expand_path('../lib', __FILE__) 3 | $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib) 4 | 5 | Gem::Specification.new do |spec| 6 | spec.name = "activerecord-postgresql-citext" 7 | spec.version = "0.2.0" 8 | spec.authors = ["Braintree"] 9 | spec.email = ["code@getbraintree.com"] 10 | spec.description = "citext support for rails" 11 | spec.summary = "citext support for rails" 12 | spec.homepage = "https://github.com/braintree/activerecord-postgresql-citext" 13 | spec.license = "MIT" 14 | 15 | spec.files = `git ls-files`.split($/) 16 | spec.executables = [] 17 | spec.test_files = spec.files.grep(%r{^spec/}) 18 | spec.require_paths = ["lib"] 19 | 20 | spec.add_dependency "activerecord", ">= 4.0.0", "< 4.2.0" 21 | spec.add_dependency "pg" 22 | 23 | spec.add_development_dependency "rake" 24 | spec.add_development_dependency "rspec", "= 2.14.1" 25 | end 26 | -------------------------------------------------------------------------------- /lib/activerecord/postgresql/citext.rb: -------------------------------------------------------------------------------- 1 | require 'active_record/connection_adapters/postgresql_adapter' 2 | 3 | ActiveRecord::ConnectionAdapters::TableDefinition.class_eval do 4 | def citext(*args) 5 | options = args.extract_options! 6 | column(args[0], 'citext', options) 7 | end 8 | end 9 | 10 | ActiveRecord::ConnectionAdapters::Column.class_eval do 11 | def simplified_type_with_citext_support(field_type) 12 | if field_type == "citext" 13 | :citext 14 | else 15 | simplified_type_without_citext_support(field_type) 16 | end 17 | end 18 | alias_method_chain :simplified_type, :citext_support 19 | end 20 | 21 | ActiveRecord::ConnectionAdapters::PostgreSQLColumn.class_eval do 22 | def self.extract_value_from_default_with_citext_support(default) 23 | if default =~ /\A'(.*)'::(?:citext)\z/m 24 | $1 25 | else 26 | extract_value_from_default_without_citext_support(default) 27 | end 28 | end 29 | class << self 30 | alias_method_chain :extract_value_from_default, :citext_support 31 | end 32 | end 33 | 34 | ActiveRecord::ConnectionAdapters::PostgreSQLAdapter.class_eval do 35 | def native_database_types_with_citext 36 | native_database_types_without_citext.merge( 37 | :citext => { :name => "citext" } 38 | ) 39 | end 40 | alias_method_chain :native_database_types, :citext 41 | end 42 | 43 | ActiveRecord::ConnectionAdapters::PostgreSQLAdapter::OID.alias_type "citext", "text" 44 | -------------------------------------------------------------------------------- /spec/citext_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | class Model < ActiveRecord::Base; end 4 | 5 | describe "citext" do 6 | before(:each) do 7 | ActiveRecord::Schema.define do 8 | self.verbose = false 9 | 10 | enable_extension("citext") 11 | 12 | create_table :models, :force => true do |t| 13 | t.citext :name 14 | t.timestamps 15 | end 16 | end 17 | end 18 | 19 | it "can create citext columns" do 20 | name_column = Model.columns.detect {|c| c.name == "name"} 21 | name_column.sql_type.should == "citext" 22 | name_column.type.should == :citext 23 | end 24 | 25 | it "save citext contents as a string" do 26 | Model.create! name: "123" 27 | Model.first.name.should == "123" 28 | end 29 | end 30 | -------------------------------------------------------------------------------- /spec/spec_helper.rb: -------------------------------------------------------------------------------- 1 | $LOAD_PATH.unshift File.expand_path('../lib/', __FILE__) 2 | require 'active_record' 3 | require 'activerecord/postgresql/citext' 4 | # This file was generated by the `rspec --init` command. Conventionally, all 5 | # specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`. 6 | # Require this file using `require "spec_helper"` to ensure that it is only 7 | # loaded once. 8 | # 9 | # See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration 10 | 11 | config = { 12 | :adapter => 'postgresql', 13 | :template => 'template0', 14 | :schema_search_path => 'public', 15 | :database => 'activerecord_postgresql_citext', 16 | :username => ENV["DB_USERNAME"] || ENV["USER"], 17 | :password => ENV["DB_PASSWORD"], 18 | :host => 'localhost', 19 | :port => ENV["DB_PORT"] || 5433 20 | } 21 | ActiveRecord::Base.establish_connection(config) 22 | 23 | RSpec.configure do |config| 24 | config.treat_symbols_as_metadata_keys_with_true_values = true 25 | config.run_all_when_everything_filtered = true 26 | config.filter_run :focus 27 | config.order = 'random' 28 | config.around(:each) do |spec| 29 | ActiveRecord::Base.transaction do 30 | spec.run 31 | raise ActiveRecord::Rollback 32 | end 33 | end 34 | end 35 | --------------------------------------------------------------------------------