here's my code:
init file:
require 'sequel'
DB = Sequel.connect('sqlite://data.db')
DB.drop_table?(:restaurants)
DB.create_table :restaurants do
primary_key :id
String :name
end
DB.drop_table?(:category)
DB.create_table :category do
primary_key :id
String :name
end
DB.drop_table?(:items)
DB.create_table :items do
primary_key :id
foreign_key :restaurant_id
foreign_key :category_name
String :name
Float :price
end
require_relative './restaurant'
require_relative './categories'
require_relative './item'
app file:
require_relative './models/init
p = Category.create(:name => 'Pizza')
c = Category.create(:name => 'Calazone')
pa = Category.create(:name => 'Pasta')
s = Category.create(:name => 'Salad')
d = Category.create(:name => 'Dessert')
dr = Category.create(:name => 'Drink')
si = Category.create(:name => 'Side')`
But I am getting this error:
/home/ben/.rvm/gems/ruby-1.9.3-p385/gems/sequel-3.45.0/lib/sequel/model/base.rb:1780:in `block in set_restricted': method name= doesn't exist (Sequel::Error)
from /home/ben/.rvm/gems/ruby-1.9.3-p385/gems/sequel-3.45.0/lib/sequel/model/base.rb:1767:in `each'
from /home/ben/.rvm/gems/ruby-1.9.3-p385/gems/sequel-3.45.0/lib/sequel/model/base.rb:1767:in `set_restricted'
from /home/ben/.rvm/gems/ruby-1.9.3-p385/gems/sequel-3.45.0/lib/sequel/model/base.rb:1278:in `set'
from /home/ben/.rvm/gems/ruby-1.9.3-p385/gems/sequel-3.45.0/lib/sequel/model/base.rb:1736:in `initialize_set'
from /home/ben/.rvm/gems/ruby-1.9.3-p385/gems/sequel-3.45.0/lib/sequel/model/base.rb:920:in `initialize'
from /home/ben/.rvm/gems/ruby-1.9.3-p385/gems/sequel-3.45.0/lib/sequel/model/base.rb:156:in `new'
from /home/ben/.rvm/gems/ruby-1.9.3-p385/gems/sequel-3.45.0/lib/sequel/model/base.rb:156:in `create'
from app.rb:4:in `<main>'"
Help Please.
Thanks
You don't post your Category model, but I'm guessing it's not actually looking at the category table (probably the categories table). You either want to rename your database table to categories or tell your Category model to use the category table. If that's not it, you probably want to post your model code.
Related
I ran rake db:migrate and I came across this error in terminal
SQLite3::SQLException: no such table: admin_users: ALTER TABLE "admin_users" ADD "username" varchar(25)/Users/IsaiahxD/.rvm/gems/ruby-2.2.1/gems/sqlite3-1.3.10/lib/sqlite3/database.rb:91:in `initialize'
/Users/IsaiahxD/.rvm/gems/ruby-2.2.1/gems/sqlite3-1.3.10/lib/sqlite3/database.rb:91:in `new'
/Users/IsaiahxD/.rvm/gems/ruby-2.2.1/gems/sqlite3-1.3.10/lib/sqlite3/database.rb:91:in `prepare'
/Users/IsaiahxD/.rvm/gems/ruby-2.2.1/gems/sqlite3-1.3.10/lib/sqlite3/database.rb:134:in `execute'
/Users/IsaiahxD/.rvm/gems/ruby-2.2.1/gems/activerecord-4.2.3/lib/active_record/connection_adapters/sqlite3_adapter.rb:329:in `block in execute'
/Users/IsaiahxD/.rvm/gems/ruby-2.2.1/gems/activerecord-4.2.3/lib/active_record/connection_adapters/abstract_adapter.rb:473:in `block in log'
I looked into my alter_user.rb file class AlterUsers < ActiveRecord::Migration
this is the file 20150825065823_alter_users.rb
def up
rename_table("users", "admin_users.broken")
add_column("admin_users", "username", :string, :limit => 25, :after => "email" )
change_column("admin_users", "email", :string, :limit => 100)
rename_column("admin_users", "broken", "hashed_password")
puts "*** Adding an index is next ***"
add_index("admin_users", "username")
end
def down
remove_index("admin_users", "username")
rename_column("admin_users", "hashed_password", "password")
change_column("admin_users", "email", :string, :default => "" , :null => false)
remove_column("admin_users", "username")
rename_table("admin_users", "users")
end
In your #up method, you're adding columns to admin_users but you haven't defined that table yet.
Instead of:
rename_table("users", "admin_users.broken")
try:
rename_table("users", "admin_users")
I have a table in SQLite and when an entry is made in this table, I would like to create a new table for each entry in the first table. (I want to do this in Ruby On Rails, if that helps)
Here is an example to clarify what I am trying to achieve:
Assume there is a table: Campaigns
Campaigns
Campaign_ID, date, name
So if I make an entry:
01 06/12 FirstCampaign
is there a way to create a new table called: {Campaign_ID}_Page
i.e:
01_Page
(fields for this table go here)
Why do you need it?
I think it would be better to create a table Pages with a foreign key to your table Campaigns.
An example (I use Sequel):
require 'sequel'
DB = Sequel.sqlite
DB.create_table :Campaigns do
primary_key :id
column :campaign_id, :integer
column :date, :date
column :name, :string
end
DB.create_table :Pages do
primary_key :id
foreign_key :campaign_id, :Campaigns
column :text, :string
end
key = DB[:Campaigns].insert(:campaign_id => 01, :date=> Date.new(2012,1,1), :name => 'FirstCampaign')
DB[:Pages].insert(:campaign_id => key, :text => 'text for FirstCampaign')
key = DB[:Campaigns].insert(:campaign_id => 02, :date=> Date.new(2012,1,1), :name => 'SecondCampaign')
DB[:Pages].insert(:campaign_id => key, :text => 'text for SecndCampaign')
#All pages for 1st campaign
p DB[:Pages].filter(
:campaign_id => DB[:Campaigns].filter(:campaign_id => 1).first[:id]
).all
But to answer your question: You could try to use a model hook.
An example with Sequel:
require 'sequel'
DB = Sequel.sqlite
DB.create_table :Campaigns do
primary_key :id
column :campaign_id, :integer
column :date, :date
column :name, :string
end
class Campaign < Sequel::Model
def after_create
tabname = ("%05i_page" % self.campaign_id).to_sym
puts "Create table #{tabname}"
self.db.create_table( tabname ) do
foreign_key :campaign
end
end
end
p DB.table_exists?(:'01_page') #-> false, table does not exist
Campaign.create(:campaign_id => 01, :date=> Date.new(2012,1,1), :name => 'FirstCampaign')
p DB.table_exists?(:'00001_page') #-> true Table created
My example has no test, if the table already exist. If you really want to use it,
I've encountered some problems with MongoID. I have three models:
require 'mongoid'
class Configuration
include Mongoid::Document
belongs_to :user
field :links, :type => Array
field :root, :type => String
field :objects, :type => Array
field :categories, :type => Array
has_many :entries
end
class TimeDim
include Mongoid::Document
field :day, :type => Integer
field :month, :type => Integer
field :year, :type => Integer
field :day_of_week, :type => Integer
field :minute, :type => Integer
field :hour, :type => Integer
has_many :entries
end
class Entry
include Mongoid::Document
belongs_to :configuration
belongs_to :time_dim
field :category, :type => String
# any other dynamic fields
end
Creating documents for Configurations and TimeDims is successful. But when i've trying to execute following code:
params = Hash.new
params[:configuration] = config # an instance of Configuration from DB
entry.each do |key, value|
params[key.to_sym] = value # String
end
unless Entry.exists?(conditions: params)
params[:time_dim] = self.generate_time_dim # an instance of TimeDim from DB
params[:category] = self.detect_category(descr) # String
Entry.new(params).save
end
... i saw following output:
/home/scepion1d/Workspace/RubyMine/dana-x/.bundle/ruby/1.9.1/gems/bson-1.6.1/lib/bson/bson_c.rb:24:in `serialize': Cannot serialize an object of class Configuration into BSON. (BSON::InvalidDocument)
from /home/scepion1d/Workspace/RubyMine/dana-x/.bundle/ruby/1.9.1/gems/bson-1.6.1/lib/bson/bson_c.rb:24:in `serialize'
from /home/scepion1d/Workspace/RubyMine/dana-x/.bundle/ruby/1.9.1/gems/mongo-1.6.1/lib/mongo/cursor.rb:604:in `construct_query_message'
from /home/scepion1d/Workspace/RubyMine/dana-x/.bundle/ruby/1.9.1/gems/mongo-1.6.1/lib/mongo/cursor.rb:465:in `send_initial_query'
from /home/scepion1d/Workspace/RubyMine/dana-x/.bundle/ruby/1.9.1/gems/mongo-1.6.1/lib/mongo/cursor.rb:458:in `refresh'
from /home/scepion1d/Workspace/RubyMine/dana-x/.bundle/ruby/1.9.1/gems/mongo-1.6.1/lib/mongo/cursor.rb:128:in `next'
from /home/scepion1d/Workspace/RubyMine/dana-x/.bundle/ruby/1.9.1/gems/mongo-1.6.1/lib/mongo/db.rb:509:in `command'
from /home/scepion1d/Workspace/RubyMine/dana-x/.bundle/ruby/1.9.1/gems/mongo-1.6.1/lib/mongo/cursor.rb:191:in `count'
from /home/scepion1d/Workspace/RubyMine/dana-x/.bundle/ruby/1.9.1/gems/mongoid-2.4.6/lib/mongoid/cursor.rb:42:in `block in count'
from /home/scepion1d/Workspace/RubyMine/dana-x/.bundle/ruby/1.9.1/gems/mongoid-2.4.6/lib/mongoid/collections/retry.rb:29:in `retry_on_connection_failure'
from /home/scepion1d/Workspace/RubyMine/dana-x/.bundle/ruby/1.9.1/gems/mongoid-2.4.6/lib/mongoid/cursor.rb:41:in `count'
from /home/scepion1d/Workspace/RubyMine/dana-x/.bundle/ruby/1.9.1/gems/mongoid-2.4.6/lib/mongoid/contexts/mongo.rb:93:in `count'
from /home/scepion1d/Workspace/RubyMine/dana-x/.bundle/ruby/1.9.1/gems/mongoid-2.4.6/lib/mongoid/criteria.rb:45:in `count'
from /home/scepion1d/Workspace/RubyMine/dana-x/.bundle/ruby/1.9.1/gems/mongoid-2.4.6/lib/mongoid/finders.rb:60:in `exists?'
from /home/scepion1d/Workspace/RubyMine/dana-x/crawler/crawler.rb:110:in `block (2 levels) in push_entries_to_db'
from /home/scepion1d/Workspace/RubyMine/dana-x/crawler/crawler.rb:103:in `each'
from /home/scepion1d/Workspace/RubyMine/dana-x/crawler/crawler.rb:103:in `block in push_entries_to_db'
from /home/scepion1d/Workspace/RubyMine/dana-x/crawler/crawler.rb:102:in `each'
from /home/scepion1d/Workspace/RubyMine/dana-x/crawler/crawler.rb:102:in `push_entries_to_db'
from main_starter.rb:15:in `<main>'
Can anyone tell what am I doing wrong?
Mongoid doesn't support the Mass assignment with Mongoid::Document. You need all the time pass by some Hash.
If you have define an accepts_nested_attributes_for on this relation you can override it by using a attr_attributes params.
This behavior is the same that ActiveRecord.
I want to store two models using active record, but delete doesn't work as expected.
Evaluation has id, name and description
and SqlEvaluation has additional two columns of query_string and database.
I want to use those two tables, and eval_typ_id is used to distinguish which subclass should be used: 1 for SqlEvaluation.
create table eval (
eval_id int,
eval_name varchar,
eval_desc varchar,
eval_typ_id int
);
create table sql_eval (
eval_id int
query_str varchar
database varchar
);
After some research, I used the following code, it works well except "delete", which didn't delete the row in sql_eval. I cannot figure out where is wrong?
require 'rubygems'
require 'active_record'
require 'logger'
ActiveRecord::Base.logger = Logger.new(STDOUT)
ActiveRecord::Base.establish_connection(:adapter => "ibm_db",
:username => "edwdq",
:password => "edw%2dqr",
:database => "EDWV2",
:schema => "EDWDQ" )
class Eval < ActiveRecord::Base
set_table_name "eval"
set_primary_key :eval_id
TYPE_MAP = { 1 => 'SqlEval' }
class << self
def find_sti_class(type)
puts "#{type}"
super(TYPE_MAP[type.to_i])
end
def sti_name
TYPE_MAP.invert[self.name]
end
end
set_inheritance_column :eval_typ_id
end
class SqlEval < Eval
has_one :details, :class_name=>'SqlEvalDetails', :primary_key=>:eval_id, :foreign_key=>:eval_id, :include=>true, :dependent=>:delete
default_scope :conditions => { :eval_typ_id => 1 }
end
class SqlEvalDetails < ActiveRecord::Base
belongs_to :sql_eval, :class_name=>'SqlEval',
:conditions => { :eval_type_id => 1 }
set_table_name "sql_eval"
set_primary_key :eval_id
end
se = SqlEval.find(:last)
require 'pp'
pp se
pp se.details
# Eval.delete(se.eval_id)
se.delete
Sorry for messing the code. It is first time to post for me. Here is the code.
require 'rubygems'
require 'active_record'
require 'logger'
ActiveRecord::Base.logger = Logger.new(STDOUT)
ActiveRecord::Base.establish_connection(:adapter => "ibm_db",
:username => "edwdq",
:password => "edw%2dqr",
:database => "EDWV2",
:schema => "EDWDQ" )
class Eval < ActiveRecord::Base
set_table_name "eval"
set_primary_key :eval_id
TYPE_MAP = { 1 => 'SqlEval' }
class << self
def find_sti_class(type)
puts "#{type}"
super(TYPE_MAP[type.to_i])
end
def sti_name
TYPE_MAP.invert[self.name]
end
end
set_inheritance_column :eval_typ_id
end
class SqlEval < Eval
has_one :details, :class_name=>'SqlEvalDetails', :primary_key=>:eval_id, :foreign_key=>:eval_id, :include=>true, :dependent=>:delete
default_scope :conditions => { :eval_typ_id => 1 }
end
class SqlEvalDetails < ActiveRecord::Base
belongs_to :sql_eval, :class_name=>'SqlEval',
:conditions => { :eval_type_id => 1 }
set_table_name "sql_eval"
set_primary_key :eval_id
end
se = SqlEval.find(:last)
e = Eval.where(:eval_id => 26)
require 'pp'
pp se
pp e
pp se.details
# Eval.delete(se.eval_id)
se.delete
I have the following ActiveRecord testcase that mimics my problem. I have a People table with one attribute being a date. I create a view over that table adding one column which is just that date plus 20 minutes:
#!/usr/bin/env ruby
%w|pp rubygems active_record irb active_support date|.each {|lib| require lib}
ActiveRecord::Base.establish_connection(
:adapter => "sqlite3",
:database => "test.db"
)
ActiveRecord::Schema.define do
create_table :people, :force => true do |t|
t.column :name, :string
t.column :born_at, :datetime
end
execute "create view clowns as select p.name, p.born_at, datetime(p.born_at, '+' || '20' || ' minutes') as twenty_after_born_at from people p;"
end
class Person < ActiveRecord::Base
validates_presence_of :name
end
class Clown < ActiveRecord::Base
end
Person.create(:name => "John", :born_at => DateTime.now)
pp Person.all.first.born_at.class
pp Clown.all.first.born_at.class
pp Clown.all.first.twenty_after_born_at.class
The problem is, the output is
Time
Time
String
When I expect the new datetime attribute of the view to be also a Time or DateTime in the ruby world. Any ideas?
I also tried:
create view clowns as select p.name, p.born_at, CAST(datetime(p.born_at, '+' || '20' || ' minutes') as datetime) as twenty_after_born_at from people p;
With the same result.
Well, after more investigation, I found that:
MySQL works:
%w|pp rubygems active_record irb active_support date|.each {|lib| require lib}
ActiveRecord::Base.establish_connection(
:adapter => "mysql",
:username => "root",
:database => "test2"
)
ActiveRecord::Schema.define do
create_table :people, :force => true do |t|
t.column :name, :string
t.column :born_at, :datetime
end
execute "create view clowns as select p.name, p.born_at, (p.born_at + INTERVAL 20 MINUTE) as twenty_after_born_at from people p;"
end
class Person < ActiveRecord::Base
validates_presence_of :name
end
class Clown < ActiveRecord::Base
end
Person.create(:name => "John", :born_at => DateTime.now)
pp Person.all.first.born_at.class
pp Clown.all.first.born_at.class
pp Clown.all.first.twenty_after_born_at.class
Produces:
Time
Time
Time
Reading the sqlite3 adapter source code, I found out that it uses PRAGMA table_info(table_name) to get the type information, and that does not return the types for views:
sqlite> pragma table_info('people');
0|id|INTEGER|1||1
1|name|varchar(255)|0||0
2|born_at|datetime|0||0
sqlite> pragma table_info('clowns');
0|name|varchar(255)|0||0
1|born_at|datetime|0||0
2|twenty_after_born_at||0||0
Therefore it may be a limitation of the adapter or just a sqlite3's views limitation. I have opened a ticket for ActiveRecord:
Also, quoting this mail in sqlite-users:
RoR should be using the
sqlite3_column_type() API to determine
the type of the values returned from a
query. Other APIs like
sqlite3_column_decltype() and pragma
table_info are returning other
information, not the type of the
result value.
Well, basically there is no datatime type in SQLite as opposed to MySQL. In your example you explicitly define types for the table but do not specify types for the view. That might be the problem. Can not check it since I have never touched ruby.