Help with understanding railing db test

37 views
Skip to first unread message

Weston Platter

unread,
Sep 19, 2012, 3:14:51 AM9/19/12
to rubyonra...@googlegroups.com
When I run a RSpec test for (JRuby + sqlite), but not (Ruby 1.9.3 + [mysql | postgres])
describe SomeModel do
  it { should have_db_index(:name).unique(true) }
end


The spec fails even though the schema.rb shows the db field as unquiely indexed.
ActiveRecord::Schema.define(:version => 20120908004000) do
  create_table "some_model", :force => true do |t|
    t.string "name", :limit => 63, :null => false
  end
  add_index "apps", ["name"], :name => "index_apps_on_name", :unique => true
end

The issue seems to be that MySQL and Postgres connection adapters behave differently than the Sqlite. 
So I did some digging. The shoulda matchers use this to evaluate index uniqueness.
::ActiveRecord::Base.connection.indexes(App.table_name).detect {|e| e.columns == ["name"]}

# sqlite
<struct ActiveRecord::ConnectionAdapters::IndexDefinition table="apps", name="index_apps_on_name", unique=7, columns=["name"], lengths=nil, orders=nil>
# mysql
<struct ActiveRecord::ConnectionAdapters::IndexDefinition table="apps", name="index_apps_on_name", unique=true, columns=["name"], lengths=nil, orders=nil>
# postgres
<struct ActiveRecord::ConnectionAdapters::IndexDefinition table="apps", name="index_apps_on_name", unique=true, columns=["name"], lengths=nil, orders=nil>


The difference is mysql2: unqiue = true, pg: unique = true, sqlite: unique = 7.

(1) 
Is Sqlite unique supposed to be 7?
I don't think so.

(2) 
If not, anyone know where would I go to refactor this? 
Somewhere in ActiveRecord::ConnectionAdapters::SQLiteAdapter
I tried looking in api.rubyonrails.org, but Postgres was the only adapter with the indexes method.


Steve Klabnik

unread,
Sep 19, 2012, 3:26:06 AM9/19/12
to rubyonra...@googlegroups.com
In Ruby,

$ irb
1.9.3-p194 :001 > if 7
1.9.3-p194 :002?> puts "hey"
1.9.3-p194 :003?> end
hey

Sounds like someone's got a bug. It should be just as true as the other ones.

Here is the location of indexes in the SQLiteAdapter:
https://github.com/rails/rails/blob/master/activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb#L400

You can't assume the documentation always has everything in it.

Weston Platter

unread,
Sep 19, 2012, 3:27:34 AM9/19/12
to rubyonra...@googlegroups.com
awesome. thanks.



Steve Klabnik

unread,
Sep 19, 2012, 3:28:23 AM9/19/12
to rubyonra...@googlegroups.com
Oh, and in 3-2-stable, it's here:
https://github.com/rails/rails/blob/3-2-stable/activerecord/lib/active_record/connection_adapters/sqlite_adapter.rb#L361

But seriously, seems like Shoulda has a bug, not Rails.

Steve Klabnik

unread,
Sep 19, 2012, 3:33:37 AM9/19/12
to rubyonra...@googlegroups.com
Yeah, if I'm reading this right,
https://github.com/thoughtbot/shoulda-matchers/blob/master/lib/shoulda/matchers/active_record/have_db_index_matcher.rb#L65
is the offending line.

I'd make this code more like


is_unique = matched_index.unique

is_unique = not is_unique unless @options[:unique]

unless is_unique
@missing = "#{table_name} has an index named #{matched_index.name} " <<
"of unique #{matched_index.unique}, not #{@options[:unique]}."
end


Of course, I just did that in vim, no tests, so I might have screwed it up...

Weston Platter

unread,
Sep 19, 2012, 3:38:44 AM9/19/12
to rubyonra...@googlegroups.com
That would help.

It might also be a jruby issue.

ruby 1.9.3p194 (2012-04-20 revision 35410) [x86_64-darwin12.1.0]
#<Enumerator: [#<struct ActiveRecord::ConnectionAdapters::IndexDefinition table="apps", name="index_apps_on_name", unique=true, columns=["name"], lengths=nil, orders=nil>]:detect> 

jruby 1.6.7.2 (ruby-1.9.2-p312) (2012-05-01 26e08ba) (Java HotSpot(TM) 64-Bit Server VM 1.7.0_07) [darwin-x86_64-java]
#<Enumerator: [#<struct ActiveRecord::ConnectionAdapters::IndexDefinition table="apps", name="index_apps_on_name", unique=7, columns=["name"], lengths=nil, orders=nil>]:detect>

Weston Platter

unread,
Sep 19, 2012, 3:44:55 AM9/19/12
to rubyonra...@googlegroups.com
I'll test it on the rails-dev-box thingee tomorrow to make sure it's not my env.

Steve Klabnik

unread,
Sep 19, 2012, 3:45:04 AM9/19/12
to rubyonra...@googlegroups.com
Let's see what team shoulda has to say:
https://github.com/thoughtbot/shoulda-matchers/pull/156
Reply all
Reply to author
Forward
0 new messages