使用Rails 3和sqlite3在acts_as_taggable_on gem中缺少列错误

时间:2012-09-30 13:34:49

标签: ruby-on-rails-3 sqlite acts-as-taggable-on

我认为我在行为中发现了一个奇怪的错误标签。其他人可以重现此错误吗? 从裸Rails 3项目开始:

~ [13:57:32]: cd Development/
~/Development [13:59:44]: rvm use 1.9.3
Using /Users/andywhite/.rvm/gems/ruby-1.9.3-p194
Running /Users/andywhite/.rvm/hooks/after_use
~/Development [13:59:54]: rails -v
Rails 3.2.8
~/Development [14:00:01]: rails new foo --skip-bundle
      create  
      create  README.rdoc
      create  Rakefile
      create  config.ru
      create  .gitignore
      create  Gemfile
      create  app
      (snip)
      create  vendor/assets/javascripts/.gitkeep
      create  vendor/assets/stylesheets
      create  vendor/assets/stylesheets/.gitkeep
      create  vendor/plugins
      create  vendor/plugins/.gitkeep
~/Development [14:00:21]: cd foo
~/Development/foo [14:01:26]: rvm --rvmrc --create 1.9.3@foo
~/Development/foo [14:02:38]: cd ..
~/Development [14:02:40]: cd -
/Users/andywhite/Development/foo
====================================================================================
= NOTICE                                                                           =
====================================================================================
= RVM has encountered a new or modified .rvmrc file in the current directory       =
= This is a shell script and therefore may contain any shell commands.             =
=                                                                                  =
= Examine the contents of this file carefully to be sure the contents are          =
= safe before trusting it! ( Choose v[iew] below to view the contents )            =
====================================================================================
Do you wish to trust this .rvmrc file? (/Users/andywhite/Development/foo/.rvmrc)
y[es], n[o], v[iew], c[ancel]> yes
~/Development/foo [14:02:44]: vi Gemfile 
~/Development/foo [14:08:18]: cat Gemfile 
source 'http://rubygems.org'

gem 'rails', '3.2.8'

# Bundle edge Rails instead:
# gem 'rails', :git => 'git://github.com/rails/rails.git'

gem 'sqlite3'


# Gems used only for assets and not required
# in production environments by default.
group :assets do
  gem 'sass-rails',   '~> 3.2.3'
  gem 'coffee-rails', '~> 3.2.1'

  # See https://github.com/sstephenson/execjs#readme for more supported runtimes
  # gem 'therubyracer', :platforms => :ruby

  gem 'uglifier', '>= 1.0.3'
end

gem 'jquery-rails'

# To use ActiveModel has_secure_password
# gem 'bcrypt-ruby', '~> 3.0.0'

# To use Jbuilder templates for JSON
# gem 'jbuilder'

# Use unicorn as the app server
# gem 'unicorn'

# Deploy with Capistrano
# gem 'capistrano'

# To use debugger
# gem 'debugger'
gem 'acts-as-taggable-on'
~/Development/foo [14:08:26]: bundle
Fetching gem metadata from http://rubygems.org/.........
Using rake (0.9.2.2) 
Installing i18n (0.6.1) 
Installing multi_json (1.3.6) 
Installing activesupport (3.2.8) 
Installing builder (3.0.3) 
Installing activemodel (3.2.8) 
Installing erubis (2.7.0) 
Installing journey (1.0.4) 
Installing rack (1.4.1) 
Installing rack-cache (1.2) 
Installing rack-test (0.6.2) 
Installing hike (1.2.1) 
Installing tilt (1.3.3) 
Installing sprockets (2.1.3) 
Installing actionpack (3.2.8) 
Installing mime-types (1.19) 
Installing polyglot (0.3.3) 
Installing treetop (1.4.10) 
Installing mail (2.4.4) 
Installing actionmailer (3.2.8) 
Installing arel (3.0.2) 
Installing tzinfo (0.3.33) 
Installing activerecord (3.2.8) 
Installing activeresource (3.2.8) 
Using bundler (1.2.0) 
Installing rack-ssl (1.3.2) 
Installing json (1.7.5) with native extensions 
Installing rdoc (3.12) 
Installing thor (0.16.0) 
Installing railties (3.2.8) 
Installing rails (3.2.8) 
Installing acts-as-taggable-on (2.3.3) 
Installing coffee-script-source (1.3.3) 
Installing execjs (1.4.0) 
Installing coffee-script (2.2.0) 
Installing coffee-rails (3.2.2) 
Installing jquery-rails (2.1.3) 
Installing sass (3.2.1) 
Installing sass-rails (3.2.5) 
Installing sqlite3 (1.3.6) with native extensions 
Installing uglifier (1.3.0) 
Your bundle is complete! Use `bundle show [gemname]` to see where a bundled gem is installed.
Post-install message from rdoc:
Depending on your version of ruby, you may need to install ruby rdoc/ri data:

<= 1.8.6 : unsupported
 = 1.8.7 : gem install rdoc-data; rdoc-data --install
 = 1.9.1 : gem install rdoc-data; rdoc-data --install
>= 1.9.2 : nothing to do! Yay!

~/Development/foo [14:08:58]: rails g model Post body
      invoke  active_record
      create    db/migrate/20120930130941_create_posts.rb
      create    app/models/post.rb
      invoke    test_unit
      create      test/unit/post_test.rb
      create      test/fixtures/posts.yml
~/Development/foo [14:09:41]: rails g  acts_as_taggable_on:migration
      create  db/migrate/20120930131032_acts_as_taggable_on_migration.rb
~/Development/foo [14:10:31]: rake db:migrate
==  CreatePosts: migrating ====================================================
-- create_table(:posts)
   -> 0.0014s
==  CreatePosts: migrated (0.0015s) ===========================================

==  ActsAsTaggableOnMigration: migrating ======================================
-- create_table(:tags)
   -> 0.0013s
-- create_table(:taggings)
   -> 0.0012s
-- add_index(:taggings, :tag_id)
   -> 0.0005s
-- add_index(:taggings, [:taggable_id, :taggable_type, :context])
   -> 0.0007s
==  ActsAsTaggableOnMigration: migrated (0.0043s) =============================

~/Development/foo [14:10:41]: vi app/models/post.rb 
~/Development/foo [14:11:32]: cat app/models/post.rb 
class Post < ActiveRecord::Base
  attr_accessible :body, :tag_list
  acts_as_taggable
end
~/Development/foo [14:11:42]: rails c
Loading development environment (Rails 3.2.8)
1.9.3-p194 :001 > p = Post.create :body => 'My hat blew off'
   (0.1ms)  begin transaction
  SQL (217.4ms)  INSERT INTO "posts" ("body", "created_at", "updated_at") VALUES (?, ?, ?)  [["body", "My hat blew off"], ["created_at", Sun, 30 Sep 2012 13:12:28 UTC +00:00], ["updated_at", Sun, 30 Sep 2012 13:12:28 UTC +00:00]]
   (2.8ms)  commit transaction
 => #<Post id: 1, body: "My hat blew off", created_at: "2012-09-30 13:12:28", updated_at: "2012-09-30 13:12:28"> 
1.9.3-p194 :002 > p.tag_list = "news, boring, hats"
  ActsAsTaggableOn::Tag Load (0.2ms)  SELECT "tags".* FROM "tags" INNER JOIN "taggings" ON "tags"."id" = "taggings"."tag_id" WHERE "taggings"."taggable_id" = 1 AND "taggings"."taggable_type" = 'Post' AND (taggings.context = 'tags' AND taggings.tagger_id IS NULL)
 => "news, boring, hats" 
1.9.3-p194 :003 > p.save
   (0.1ms)  begin transaction
   (0.6ms)  UPDATE "posts" SET "updated_at" = '2012-09-30 13:13:28.210803' WHERE "posts"."id" = 1
  ActsAsTaggableOn::Tag Load (0.1ms)  SELECT "tags".* FROM "tags" WHERE (lower(name) = 'news' OR lower(name) = 'boring' OR lower(name) = 'hats')
  ActsAsTaggableOn::Tag Exists (0.1ms)  SELECT 1 AS one FROM "tags" WHERE "tags"."name" = 'news' LIMIT 1
  SQL (0.2ms)  INSERT INTO "tags" ("name") VALUES (?)  [["name", "news"]]
  ActsAsTaggableOn::Tag Exists (0.1ms)  SELECT 1 AS one FROM "tags" WHERE "tags"."name" = 'boring' LIMIT 1
  SQL (0.0ms)  INSERT INTO "tags" ("name") VALUES (?)  [["name", "boring"]]
  ActsAsTaggableOn::Tag Exists (0.1ms)  SELECT 1 AS one FROM "tags" WHERE "tags"."name" = 'hats' LIMIT 1
  SQL (0.0ms)  INSERT INTO "tags" ("name") VALUES (?)  [["name", "hats"]]
  ActsAsTaggableOn::Tag Load (0.1ms)  SELECT "tags".* FROM "tags" INNER JOIN "taggings" ON "tags"."id" = "taggings"."tag_id" WHERE "taggings"."taggable_id" = 1 AND "taggings"."taggable_type" = 'Post' AND (taggings.context = 'tags' AND taggings.tagger_id IS NULL)
  ActsAsTaggableOn::Tagging Exists (0.2ms)  SELECT 1 AS one FROM "taggings" WHERE ("taggings"."tag_id" = 1 AND "taggings"."taggable_type" = 'Post' AND "taggings"."taggable_id" = 1 AND "taggings"."context" = 'tags' AND "taggings"."tagger_id" IS NULL AND "taggings"."tagger_type" IS NULL) LIMIT 1
  SQL (0.4ms)  INSERT INTO "taggings" ("context", "created_at", "tag_id", "taggable_id", "taggable_type", "tagger_id", "tagger_type") VALUES (?, ?, ?, ?, ?, ?, ?)  [["context", "tags"], ["created_at", Sun, 30 Sep 2012 13:13:28 UTC +00:00], ["tag_id", 1], ["taggable_id", 1], ["taggable_type", "Post"], ["tagger_id", nil], ["tagger_type", nil]]
  ActsAsTaggableOn::Tagging Exists (0.1ms)  SELECT 1 AS one FROM "taggings" WHERE ("taggings"."tag_id" = 2 AND "taggings"."taggable_type" = 'Post' AND "taggings"."taggable_id" = 1 AND "taggings"."context" = 'tags' AND "taggings"."tagger_id" IS NULL AND "taggings"."tagger_type" IS NULL) LIMIT 1
  SQL (0.1ms)  INSERT INTO "taggings" ("context", "created_at", "tag_id", "taggable_id", "taggable_type", "tagger_id", "tagger_type") VALUES (?, ?, ?, ?, ?, ?, ?)  [["context", "tags"], ["created_at", Sun, 30 Sep 2012 13:13:28 UTC +00:00], ["tag_id", 2], ["taggable_id", 1], ["taggable_type", "Post"], ["tagger_id", nil], ["tagger_type", nil]]
  ActsAsTaggableOn::Tagging Exists (0.1ms)  SELECT 1 AS one FROM "taggings" WHERE ("taggings"."tag_id" = 3 AND "taggings"."taggable_type" = 'Post' AND "taggings"."taggable_id" = 1 AND "taggings"."context" = 'tags' AND "taggings"."tagger_id" IS NULL AND "taggings"."tagger_type" IS NULL) LIMIT 1
  SQL (0.1ms)  INSERT INTO "taggings" ("context", "created_at", "tag_id", "taggable_id", "taggable_type", "tagger_id", "tagger_type") VALUES (?, ?, ?, ?, ?, ?, ?)  [["context", "tags"], ["created_at", Sun, 30 Sep 2012 13:13:28 UTC +00:00], ["tag_id", 3], ["taggable_id", 1], ["taggable_type", "Post"], ["tagger_id", nil], ["tagger_type", nil]]
   (1.9ms)  commit transaction
 => true 
1.9.3-p194 :004 > p.tag_list
 => ["news", "boring", "hats"] 
1.9.3-p194 :005 > Post.tag_counts
  ActsAsTaggableOn::Tag Load (0.4ms)  SELECT tags.*, taggings.tags_count AS count FROM "tags" JOIN (SELECT taggings.tag_id, COUNT(taggings.tag_id) AS tags_count FROM "taggings" INNER JOIN posts ON posts.id = taggings.taggable_id WHERE (taggings.taggable_type = 'Post' AND taggings.context = 'tags') AND (taggings.taggable_id IN(SELECT posts.id FROM "posts" )) GROUP BY taggings.tag_id HAVING COUNT(taggings.tag_id) > 0) AS taggings ON taggings.tag_id = tags.id
ActiveRecord::StatementInvalid: SQLite3::SQLException: no such column: taggings.tag_id: SELECT tags.*, taggings.tags_count AS count FROM "tags" JOIN (SELECT taggings.tag_id, COUNT(taggings.tag_id) AS tags_count FROM "taggings" INNER JOIN posts ON posts.id = taggings.taggable_id WHERE (taggings.taggable_type = 'Post' AND taggings.context = 'tags') AND (taggings.taggable_id IN(SELECT posts.id FROM "posts" )) GROUP BY taggings.tag_id HAVING COUNT(taggings.tag_id) > 0) AS taggings ON taggings.tag_id = tags.id
  from /Users/andywhite/.rvm/gems/ruby-1.9.3-p194@foo/gems/sqlite3-1.3.6/lib/sqlite3/database.rb:91:in `initialize'
  from /Users/andywhite/.rvm/gems/ruby-1.9.3-p194@foo/gems/sqlite3-1.3.6/lib/sqlite3/database.rb:91:in `new'
  from /Users/andywhite/.rvm/gems/ruby-1.9.3-p194@foo/gems/sqlite3-1.3.6/lib/sqlite3/database.rb:91:in `prepare'
  from /Users/andywhite/.rvm/gems/ruby-1.9.3-p194@foo/gems/activerecord-3.2.8/lib/active_record/connection_adapters/sqlite_adapter.rb:246:in `block in exec_query'
  from /Users/andywhite/.rvm/gems/ruby-1.9.3-p194@foo/gems/activerecord-3.2.8/lib/active_record/connection_adapters/abstract_adapter.rb:280:in `block in log'
  from /Users/andywhite/.rvm/gems/ruby-1.9.3-p194@foo/gems/activesupport-3.2.8/lib/active_support/notifications/instrumenter.rb:20:in `instrument'
  from /Users/andywhite/.rvm/gems/ruby-1.9.3-p194@foo/gems/activerecord-3.2.8/lib/active_record/connection_adapters/abstract_adapter.rb:275:in `log'
  from /Users/andywhite/.rvm/gems/ruby-1.9.3-p194@foo/gems/activerecord-3.2.8/lib/active_record/connection_adapters/sqlite_adapter.rb:242:in `exec_query'
  from /Users/andywhite/.rvm/gems/ruby-1.9.3-p194@foo/gems/activerecord-3.2.8/lib/active_record/connection_adapters/sqlite_adapter.rb:467:in `select'
  from /Users/andywhite/.rvm/gems/ruby-1.9.3-p194@foo/gems/activerecord-3.2.8/lib/active_record/connection_adapters/abstract/database_statements.rb:18:in `select_all'
  from /Users/andywhite/.rvm/gems/ruby-1.9.3-p194@foo/gems/activerecord-3.2.8/lib/active_record/connection_adapters/abstract/query_cache.rb:63:in `select_all'
  from /Users/andywhite/.rvm/gems/ruby-1.9.3-p194@foo/gems/activerecord-3.2.8/lib/active_record/querying.rb:38:in `block in find_by_sql'
  from /Users/andywhite/.rvm/gems/ruby-1.9.3-p194@foo/gems/activerecord-3.2.8/lib/active_record/explain.rb:40:in `logging_query_plan'
  from /Users/andywhite/.rvm/gems/ruby-1.9.3-p194@foo/gems/activerecord-3.2.8/lib/active_record/querying.rb:37:in `find_by_sql'
  from /Users/andywhite/.rvm/gems/ruby-1.9.3-p194@foo/gems/activerecord-3.2.8/lib/active_record/relation.rb:171:in `exec_queries'
  from /Users/andywhite/.rvm/gems/ruby-1.9.3-p194@foo/gems/activerecord-3.2.8/lib/active_record/relation.rb:160:in `block in to_a'
  from /Users/andywhite/.rvm/gems/ruby-1.9.3-p194@foo/gems/activerecord-3.2.8/lib/active_record/explain.rb:33:in `logging_query_plan'
  from /Users/andywhite/.rvm/gems/ruby-1.9.3-p194@foo/gems/activerecord-3.2.8/lib/active_record/relation.rb:159:in `to_a'
  from /Users/andywhite/.rvm/gems/ruby-1.9.3-p194@foo/gems/activerecord-3.2.8/lib/active_record/relation.rb:498:in `inspect'
  from /Users/andywhite/.rvm/gems/ruby-1.9.3-p194@foo/gems/railties-3.2.8/lib/rails/commands/console.rb:47:in `start'
  from /Users/andywhite/.rvm/gems/ruby-1.9.3-p194@foo/gems/railties-3.2.8/lib/rails/commands/console.rb:8:in `start'
  from /Users/andywhite/.rvm/gems/ruby-1.9.3-p194@foo/gems/railties-3.2.8/lib/rails/commands.rb:41:in `<top (required)>'
  from script/rails:6:in `require'
  from script/rails:6:in `<main>'1.9.3-p194 :006 > 
1.9.3-p194 :007 >   exit

所以我们似乎缺少* taggings.tag_id *列。所以让我们进入sqlite3进行调查:

~/Development/foo [14:14:39]: sqlite3 db/development.sqlite3 
SQLite version 3.7.14 2012-09-03 15:42:36
Enter ".help" for instructions
Enter SQL statements terminated with a ";"
sqlite> .headers on
sqlite> select * from taggings;
id|tag_id|taggable_id|taggable_type|tagger_id|tagger_type|context|created_at
1|1|1|Post|||tags|2012-09-30 13:13:28.357091
2|2|1|Post|||tags|2012-09-30 13:13:28.360285
3|3|1|Post|||tags|2012-09-30 13:13:28.362351
sqlite> .schema taggings
CREATE TABLE "taggings" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "tag_id" integer, "taggable_id" integer, "taggable_type" varchar(255), "tagger_id" integer, "tagger_type" varchar(255), "context" varchar(128), "created_at" datetime);
CREATE INDEX "index_taggings_on_tag_id" ON "taggings" ("tag_id");
CREATE INDEX "index_taggings_on_taggable_id_and_taggable_type_and_context" ON "taggings" ("taggable_id", "taggable_type", "context");
sqlite> 

嗯。所以列就是那里!?让我们剪切并粘贴有问题的SQL,看看我们得到了相同的遗漏列错误:

sqlite> SELECT tags.*, taggings.tags_count AS count FROM "tags" JOIN (SELECT taggings.tag_id, COUNT(taggings.tag_id) AS tags_count FROM "taggings" INNER JOIN posts ON posts.id = taggings.taggable_id WHERE (taggings.taggable_type = 'Post' AND taggings.context = 'tags') AND (taggings.taggable_id IN(SELECT posts.id FROM "posts" )) GROUP BY taggings.tag_id HAVING COUNT(taggings.tag_id) > 0) AS taggings ON taggings.tag_id = tags.id;
id|name|count
1|news|1
2|boring|1
3|hats|1
sqlite> .exit
~/Development/foo [14:17:25]: 

什么......?有谁知道这里发生了什么。我错过了一些非常明显的东西吗?

更新(当天晚些时候): 我找到了一个workround。因此在Posts中覆盖* tag_counts *类方法:

def self.tag_counts
  ActsAsTaggableOn::Tag.select("tags.*, count(taggings.tag_id) as count").
    joins(:taggings).group("taggings.tag_id")
end

感谢Ryan Bates和他出色的Railscasts episode这个方法的出发点。 仍然有兴趣看看是否有其他人可以重现错误。

1 个答案:

答案 0 :(得分:0)

我也有同样的错误。在我的ubuntu开发环境中正常工作,但是在centos的生产中,我也得到了丢失的taggings.tag_id错误。

相同版本的ruby,rails等。