Thinking Sphinx: indexing error - ruby-on-rails

ANSWERED:
set_primary_key "QTLID" in the model to tell model that pirmary ID is not ID
I am getting this error when I rake:ts index
Cannot automatically map attribute sphinx_internal_id in QtlTable to an
equivalent Sphinx type (integer, float, boolean, datetime, string as ordinal).
You could try to explicitly convert the column's value in your define_index
block:
has "CAST(column AS INT)", :type => :integer, :as => :column
I can't figure out how to fix this.
Here is my model (note I did not setup this database so don't jump on me for terrible conventions):
class QtlTable < ActiveRecord::Base
...
define_index do
indexes :QTLID
has :QTLName
end
end
Here is what schema looks like for qtl_table:
create_table "qtl_table", :primary_key => "QTLID", :force => true do |t|
t.string "QTLName", :limit => 60, :default => "", :null => false
t.string "Parent_1", :limit => 60, :default => "", :null => false
t.string "Parent_2", :limit => 60, :default => "", :null => false
t.string "Heritability", :limit => 60, :default => ""
t.text "Population_size", :limit => 16777215
t.string "Number_plants_bulked", :limit => 10
t.text "Pop_high_score", :limit => 16777215
t.text "Pop_low_score", :limit => 16777215
t.string "Loci_tested", :limit => 10, :default => ""
t.string "Intervals_associated", :limit => 10, :default => ""
t.string "Interval_length", :limit => 6, :default => ""
t.string "Interval_LOD_score", :limit => 12, :default => ""
t.string "Interval_P_value", :limit => 6, :default => ""
t.string "Interval_R2", :limit => 6, :default => ""
t.string "Genotypic_R2", :limit => 6, :default => ""
t.text "R2_Definition", :limit => 16777215
t.string "Percent_variation_explained", :limit => 6, :default => ""
t.string "First_entered", :limit => 60, :default => "", :null => false
t.string "Last_update", :limit => 60, :default => ""
t.string "TraitName", :limit => 100, :default => ""
t.binary "in_new", :limit => 1
end
add_index "qtl_table", ["QTLName"], :name => "QTLName_index"
add_index "qtl_table", ["TraitName"], :name => "TraitName_index"
ANSWERED:
set_primary_key "QTLID" in the model to tell model that pirmary ID is not ID

set_primary_key "QTLID" in the model to tell model that pirmary ID is not ID

Related

undefined method `to_sym' for {:limit=>30, :string=>"Hint: ", :null=>false}:Hash

Why is it showing this error when i try to run rake db:migrate:
undefined method `to_sym' for {:limit=>30, :string=>"Hint: ", :null=>false}:Hash
Code:
def up
create_table :users do |t|
t.string "email", :limit => 50, :string => "Forgot password!", :null => false
t.column "password", :limit => 30, :string => "Hint: ", :null => false
:default
t.timestamps
end
end
this line may need to change..
t.column "password", :limit => 30, :string => "Hint: ", :null => false
by
t.string "password", :limit => 30, :string => "Hint: ", :null => false

why the belongs to association return a Fixnum object

rails 3.2.2
mysql2
I have the following relationships,
class TalkingCase < ActiveRecord::Base
belongs_to :medical_case
end
class MedicalCase < ActiveRecord::Base
has_many :talking_cases
end
in the console:
a=TalkingCase.first
a.medical_case
sometimes it return 0 and sometimes it work fine.
and I can use MedicalCase.find(xx) to get the medical_case object.
Do anyone meet this question?
The following is the console ouput:
Loading development environment (Rails 3.2.2)
[1] pry(main)> a=TalkingCase.first
TalkingCase Load (0.4ms) SELECT `talking_cases`.* FROM `talking_cases` LIMIT 1
=> #<TalkingCase id: 15, user_id: 231, talking_id: 7, nickname: "史丽", medical_case_id: 42, medical_case_name: "糖尿病肾病之一", created_at: "2012-06-21 03:38:36", updated_at: "2012-06-21 03:38:36">(this is ok)
[2] pry(main)> a.medical_case
MedicalCase Load (0.5ms) SELECT `medical_cases`.* FROM `medical_cases` WHERE `medical_cases`.`id` = 42 ORDER BY id desc LIMIT 1
=> 1
(this is stranger,I need the medical_case object)
tables in the schema is following:
create_table "talking_cases", :force => true do |t|
t.integer "user_id"
t.integer "talking_id"
t.string "nickname"
t.integer "medical_case_id"
t.string "medical_case_name"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
end
create_table "medical_cases", :force => true do |t|
t.string "title", :null => false
t.string "bianhao", :null => false
t.integer "age"
t.string "gender", :limit => 1
t.integer "user_id", :null => false
t.integer "is_shared", :limit => 1
t.integer "is_elite", :limit => 1
t.integer "is_recommend", :limit => 1
t.string "share_reason"
t.string "other_cate_des"
t.string "keywords"
t.integer "comments_count", :default => 0
t.integer "click_count", :default => 0
t.integer "tap", :default => 0
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
t.integer "fans_count"
end
Please specify the type of the association from the MedicalCase model too
class MedicalCase < ActiveRecord::Base
has_one :talking_case
end

How to create rows from a running number?

I'm trying write code of running numbers from document numbers, with the following values
Data in mind :
document_types records :
{:document_type_code => 'PR', :running_no => 2, ...}
{:document_type_code => 'SO', :running_no => 1, ...}
transactions records :
{:id => 1, :document_no=> 'PR000001', :document_type_code=> 'PR', ...}
{:id => 2, :document_no=> 'SO000001', :document_type_code=> 'SO', ...}
{:id => 3, :document_no=> 'PR000002', :document_type_code=> 'PR', ...}
The design:
create_table :runnings do |t|
t.string :document_type_code, :null => false, :limit => 2
t.integer :running_no, :null => false, :default => 0
...
t.timestamps
end
create_table :transactions do |t|
t.string :document_no, :null => false
t.string :document_type_code, :null => false, :limit => 2
...
t.timestamps
end
How do I generate the document_no in Transactions?
document = Transaction.new
document.document_type_code = 'PR'
document.document_no = ??????
...
document.save!
Use the ruby method 'next' :
irb(main):019:0> 'PR000001'.next
=> "PR000002"
Also you can use method 'succ':
irb(main):022:0> 'PR000001'.succ
=> "PR000002"
Take a look on link :
http://www.devarticles.com/c/a/Ruby-on-Rails/Iterating-and-Incrementing-Strings-in-Ruby/3/
EDITED :
You can get incremented document no like:
transaction = Transaction.last
transaction.nil? 'PR000001' ? : transaction.document_no.succ
OR
transaction.nil? 'PR000001' ? : transaction.document_no.next
Hope that help.
You could get the count of all the running numbers for each 'document_type_code' and increment that from 1
you may write a scope for this
HTH

Loading data in a Rails migration

I created number of migrations starting with a definition for a Posts table.
class CreatePosts < ActiveRecord::Migration
def self.up
create_table :posts do |t|
t.column "title", :string, :limit => 100, :default => "", :null => false
t.column "content", :text, :null => false
t.column "author", :string, :limit => 100, :default => 0, :null => false
t.column "category", :string, :limit => 20, :default => "", :null => false
t.column "status", :string, :limit => 20, :default => "", :null => false
t.timestamps
end
end
def self.down
drop_table :posts
end
end
And another one for a Users table in which I load some data for a default user after creating the table.
class CreateUsers < ActiveRecord::Migration
def self.up
create_table :users do |t|
t.column "username", :string, :limit => 25, :default => "", :null => false
t.column "hashed_password", :string, :limit => 40, :default => "", :null => false
t.column "first_name", :string, :limit => 25, :default => "", :null => false
t.column "last_name", :string, :limit => 40, :default => "", :null => false
t.column "email", :string, :limit => 50, :default => "", :null => false
t.column "display_name", :string, :limit => 25, :default => "", :null => false
t.column "user_level", :integer, :limit => 3, :default => 0, :null => false
t.timestamps
end
user = User.create(:username => 'bopeep',
:hashed_password => 'bopeep',
:first_name => 'Bo',
:last_name => 'Peep',
:email => 'bo#peep.com',
:display_name => 'Little Bo Peep',
:user_level => 9)
end
def self.down
drop_table :users
end
end
Next I created a migration to alter the Posts table to rename the table to blog_posts. Here I also wanted to load a default blog post entry.
class AlterPosts < ActiveRecord::Migration
def self.up
rename_table :posts, :blog_posts
change_column :blog_posts, :author, :integer, :default => 0, :null => false
rename_column :blog_posts, :author, :author_id
add_index :blog_posts, :author_id
bopeep = User.find_by_username 'bopeep'
BlogPost.create(:title => 'test', :content => 'test', :author_id => bopeep.id, :category => 'test', :status => 'ok')
end
def self.down
remove_index :blog_posts, :author_id
rename_table :blog_posts, :posts
rename_column :posts, :author_id, :author
change_column :posts, :author, :string, :limit => 100, :default => 0, :null => false
end
end
But this generates an error:
uninitialized constant AlterPosts::BlogPost
How should I have loaded the default BlogPost instead of "BlogPost.create"?
Separate your rename_table and your change/rename column migrations into another migration file.
I don't think the rename is committed until after the entire block goes through... and so therefore blog_posts does not exist yet.

counter cache doesn't update but I can save to the parent and the child

I added a counter cache but can't get it to update. But I can update the parent - the Blog Post model by adding a new blog post - and I can update the child - Comments model - by adding a new comment. The counter cache is supposed to keep track of the total number of comments per blog post by auto-updating the blog_posts.comments_count field. I'll outline some of the steps I went through and hopefully someone will notice something I did wrong. The schema dump is at the end.
I have a Blog Post model:
class Post < ActiveRecord::Base
set_table_name("blog_posts")
belongs_to :author, :class_name => "User", :foreign_key => 'author_id'
has_many :comments, :class_name => "Comment",
:foreign_key => 'post_id', :order => "created_at desc", :dependent => :destroy
has_many :categorizations
has_many :categories, :through => :categorizations
named_scope :recent, :order => "created_at desc", :limit => 5
end
and a Comments model with a counter_cache set to the post model:
class Comment < ActiveRecord::Base
belongs_to :post, :class_name => "Post", :foreign_key => "post_id", :counter_cache => true
belongs_to :author, :class_name => "User", :foreign_key => "author_id"
end
I created a migration to add the counter_cache column to the blog_posts table:
class AddCommentCounter < ActiveRecord::Migration
def self.up
add_column :blog_posts, :comments_count, :integer, :limit => 4, :default => 0, :null => false
Post.find(:all).each do |post|
current_count = post.comments.size
post.update_attribute(:comments_count, current_count)
end
end
def self.down
remove_column :blog_posts, :comments_count
end
end
But the migration fails to update the blog posts with the current_count. It's always zero.
I opened up the Rails console to try to update_attribute manually:
Loading development environment (Rails 2.3.2)
>> p = Post.find 1
p = Post.find 1
=> #<Post id: 1, title: "test", content: "test", author_id: 1, status: "ok", created_at: "2009-05-21 19:27:14", updated_at: "2009-05-24 07:02:35", comments_count: 0>
>> p.comments
p.comments
=> [#<Comment id: 5, post_id: 1, author_id: 1, content: "Fifth Comment", status: "ok", created_at: "2009-05-24 07:08:56", updated_at: "2009-05-24 07:08:56">, #<Comment id: 4, post_id: 1, author_id: 1, content: "Fourth Comment", status: "ok", created_at: "2009-05-24 07:05:32", updated_at: "2009-05-24 07:05:32">, #<Comment id: 3, post_id: 1, author_id: 1, content: "Third Comment", status: "ok", created_at: "2009-05-24 06:34:59", updated_at: "2009-05-24 06:34:59">, #<Comment id: 2, post_id: 1, author_id: 1, content: "Second Comment", status: "ok", created_at: "2009-05-24 05:20:43", updated_at: "2009-05-24 05:20:43">, #<Comment id: 1, post_id: 1, author_id: 1, content: "First Comment", status: "ok", created_at: "2009-05-21 19:27:14", updated_at: "2009-05-21 19:27:14">]
>> p.comments.size
p.comments.size
=> 5
>> p.comments_count
p.comments_count
=> 0
>> p.update_attribute(:comments_count, 5)
p.update_attribute(:comments_count, 5)
=> true
>> p.comments_count
p.comments_count
=> 5
>> p.save
p.save
=> true
But when I look in the database comments_count = 0.
Any ideas would be more than joyously appreciated.
My schema.db looks like this:
ActiveRecord::Schema.define(:version => 20090524055907) do
create_table "blog_posts", :force => true do |t|
t.string "title", :limit => 100, :default => "", :null => false
t.text "content", :null => false
t.integer "author_id", :default => 0, :null => false
t.string "status", :limit => 20, :default => "", :null => false
t.datetime "created_at"
t.datetime "updated_at"
t.integer "comments_count", :default => 0, :null => false
end
add_index "blog_posts", ["author_id"], :name => "index_blog_posts_on_author_id"
create_table "categories", :force => true do |t|
t.string "name", :limit => 50, :default => "", :null => false
t.string "short_name", :limit => 30, :default => "", :null => false
t.string "description", :default => "", :null => false
t.datetime "created_at"
t.datetime "updated_at"
end
create_table "categories_posts", :force => true do |t|
t.integer "category_id", :null => false
t.integer "post_id", :null => false
end
add_index "categories_posts", ["category_id"], :name => "index_categories_posts_on_category_id"
add_index "categories_posts", ["post_id"], :name => "index_categories_posts_on_post_id"
create_table "comments", :force => true do |t|
t.integer "post_id", :default => 0, :null => false
t.integer "author_id", :default => 0, :null => false
t.text "content", :null => false
t.string "status", :limit => 25, :default => "", :null => false
t.datetime "created_at"
t.datetime "updated_at"
end
create_table "sessions", :force => true do |t|
t.string "session_id", :default => "", :null => false
t.text "data"
t.datetime "created_at"
t.datetime "updated_at"
end
add_index "sessions", ["session_id"], :name => "index_sessions_on_session_id"
add_index "sessions", ["updated_at"], :name => "index_sessions_on_updated_at"
create_table "users", :force => true do |t|
t.string "username", :limit => 25, :default => "", :null => false
t.string "hashed_password", :limit => 40, :default => "", :null => false
t.string "first_name", :limit => 25, :default => "", :null => false
t.string "last_name", :limit => 40, :default => "", :null => false
t.string "email", :limit => 50, :default => "", :null => false
t.string "display_name", :limit => 25, :default => "", :null => false
t.integer "user_level", :limit => 3, :default => 0, :null => false
t.datetime "created_at"
t.datetime "updated_at"
end
end
Take a look at the updated code from railscasts episode 23 on counter_cache.
The counter attributes are attr_readonly. Perhaps update-counters is what you need to use in place of update attributes in your migration?

Resources