Sequel makes duplicate entries - ruby

I'm using Sequel with Sinatra and I've been trying it out and I noticed that it creates duplicate entries (3x).I've tried to debug it but in the end I couldn't understand why is this occurring.
This is my code:
require 'sinatra'
require 'mysql2'
require 'sequel'
DB=Sequel.connect(
:adapter => "mysql2",
:host =>"localhost",
:user => "root",
:password => "",
:database => "test"
)
if !DB.table_exists? :users
DB.create_table :users do
primary_key :id
String :username ,:size=>20 #,:unique=>true
String :password ,:size=>30
end
puts "Schema created"
else
puts "Already exists"
end
class User < Sequel::Model;end
class Test < Sinatra::Base
get '/:username' do
"Creating user"
User.create(:username => "#{params['username']}",:password => "test")
end
end

Related

how do I read from a Database in ruby sinatra using active record

I want to read entrys from a Database using active_record and keep getting diffrent Errors like: Name error and can't find the database or it can't execute the query.
so my question here is how do i read from a database or execute SQL-queries and for example write the result into a variable?
require 'rubygems'
require 'sinatra'
require 'active_record'
require 'sqlite3'
ActiveRecord::Base.establish_connection(
:adapter => "sqlite3",
:database => "test.db"
)
class Article < ActiveRecord::Base
end
#ActiveRecord::Migration.create_table :users do |t|
# t.string :name
#end
class App < Sinatra::Application
end
get '/' do
output = users.select(:all)
f = File.open('name','a'); f.write(output); f.close
#puts User.first
To read the data from the users table, you'd simply do:
class User < ActiveRecord::Base
end
get '/' do
#users = User.all
puts "Grabbed #{#users.size} user(s) from database"
end

Issue with Shoes setup

When i am running shoes.rb file, which contains code to install gem, it throws error.
Undefined method setup for Shoes:Class
Code:
Shoes.setup do
gem 'activerecord' # install AR if not found
require 'active_record'
require 'fileutils'
ActiveRecord::Base.establish_connection(
:adapter => 'postgresql',
:dbfile => 'shoes_app'
)
# create the db if not found
unless File.exist?("shoes_app.sqlite3")
ActiveRecord::Schema.define do
create_table :notes do |t|
t.column :message, :string
end
end
end
end
class ShoesApp < Shoes
require 'note'
url '/', :index
def index
para 'Say something...'
flow do
#note = edit_line
button 'OK' do
Note.new(:message => #note.text).save
#note.text = ''
#result.replace get_notes
end
end
#result = para get_notes
end
def get_notes
messages = []
notes = Note.find(:all, :select => 'message')
notes.each do |foo|
messages << foo.message
end
out = messages.join("n")
end
end
Shoes.app :title => 'Notes', :width => 260, :height => 350
The problem was using Shoes4, where the setup method was unimplemented.
Shoes4 now implements Shoes.setup for backwards compatibility reasons but you don't really need it, so it doesn't do anything except for printing a warning that you should rather do gem install gem_name instead of using Shoes.setup.

Uninitialized constant (NameError) when using FactoryGirl in module

Here's the error I'm getting when I try to run my tests with RSpec:
C:/Ruby193/lib/ruby/gems/1.9.1/gems/activesupport-3.2.11/lib/active_support/infl
ector/methods.rb:230:in `block in constantize': uninitialized constant User (Nam
eError)
I'm trying to run FactoryGirl with RSpec but without Rails. Here are the files that take part in the testing:
user_spec.rb
require 'spec_helper'
module Bluereader
describe User do
describe 'login' do
user = FactoryGirl.build(:user)
end
describe 'logout' do
end
describe 'create_account' do
end
describe 'delete_account' do
end
end
end
spec/spec_helper
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..'))
$LOAD_PATH.unshift(File.dirname(__FILE__))
require 'rspec'
require 'lib/bluereader'
require 'factory_girl'
FactoryGirl.find_definitions
spec/factories.rb
require 'digest/sha1'
FactoryGirl.define do
sequence(:username) { |n| "user-#{n}" }
factory :user do
username
encrypted_password Digest::SHA1.hexdigest('password')
full_name 'John Doe'
logged_in_at Time.now
logged_out_at 0
end
end
At this point I know that the factories.rb file is being loaded (I tried with the moronic print-debugging). When I remove the user = FactoryGirl.build(:user) line from user_spec.rb I get no errors (and the normal RSpec feedback telling me there are no tests, but no errors). If you are interested, here's my model:
require 'digest/sha1'
module Bluereader
class User < ActiveRecord::Base
has_many :categories, :foreign_key => :user_id
has_many :news, :foreign_key => :user_id
has_many :settings, :foreign_key => :user_id
attr_reader :full_name
class << self
def login(username, password)
encrypted_password = Digest::SHA1.hexdigest(password)
if not User.exists?(:username => username, :encrypted_password => encrypted_password)
user_id = User.id_from_username(username)
update(user_id, :logged_in_at => Time.now, :logged_out_at => 0)
end
end
def logout
update(current_user.id, :logged_out_at => Time.now)
end
def validate_account(username, password, full_name)
if username.empty? or password.empty or full_name.empty?
return 'Please fill in all the fields.'
end
if User.exists?(:username => username)
return 'That username is already in use.'
end
unless username =~ /^\w+$/
return 'Username field should contain only letters, numbers and underscores.'
end
''
end
def create_account(username, password, full_name)
encrypted_password = Digest::SHA1.hexdigest(password)
User.create(:username => username,
:encrypted_password => encrypted_password,
:full_name => full_name,
:logged_in_at => Time.now,
:logged_out_at => 0)
end
def delete_account
current_user.destroy
end
private
def id_from_username(username)
user = where(:username => username).first
user.nil? ? 0 : user.id
end
def current_user
where(:logged_out_at => 0).first
end
end
end
end
SOLUTION
The problem was that the class User was in a module, here's the solution:
factory :user, class: Bluereader::User do
You need to require the rails environment in your spec helper file. Add the following to spec/spec_helper.rb:
require File.expand_path("../../config/environment", __FILE__)
Update
Even if you're not using Rails, you'll still need to require the models in your spec helper.
Taken from the bottom of the question
The problem was that the class User was in a module, here's the solution:
factory :user, class: Bluereader::User do
For anyone clumsy like me, you may have FactoryGirl in your code where you meant to have FactoryBot

ActiveRecord STI delete doesn't work correctly

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

Sequel::Model: Where the methods like create_table come from?

I am trying to understand how Sequel works. The example below inherit from Sequel::Model and calls set_schema, create_table, etc.
I was trying to find the documentation for these methods, but no luck on the rdoc for Sequel::Model: http://sequel.rubyforge.org/rdoc/classes/Sequel/Model.html
Where are these methods coming from and how does Sequel::Model make them available?
class Task < Sequel::Model
set_schema do
primary_key :id
varchar :title, :unique => true, :empty => false
boolean :done, :default => false
end
create_table unless table_exists?
if empty?
create :title => 'Laundry'
create :title => 'Wash dishes'
end
end
They're defined in Sequel::Plugins::Schema::ClassMethods (lib/sequel/plugins/schema.rb) and included when you call plugin :schema in your model.
http://sequel.rubyforge.org/rdoc-plugins/classes/Sequel/Plugins/Schema/ClassMethods.html#M000110
http://sequel.rubyforge.org/rdoc/classes/Sequel/Model.html#M000130
The example in the question is incomplete and won't work unless a connection to a database is setup and the plugin :schema is called from the model.
irb(main):001:0> require "rubygems"
=> true
irb(main):002:0> require "sequel"
=> true
irb(main):003:0>
irb(main):004:0* # connect to an in-memory database
irb(main):005:0* DB = Sequel.sqlite
=> #<Sequel::SQLite::Database: "sqlite:/">
irb(main):006:0> class Task < Sequel::Model
irb(main):007:1> set_schema do
irb(main):008:2* primary_key :id
irb(main):009:2>
irb(main):010:2* varchar :title, :unique => true, :empty => false
irb(main):011:2> boolean :done, :default => false
irb(main):012:2> end
irb(main):013:1>
irb(main):014:1* create_table unless table_exists?
irb(main):015:1>
irb(main):016:1* if empty?
irb(main):017:2> create :title => 'Laundry'
irb(main):018:2> create :title => 'Wash dishes'
irb(main):019:2> end
irb(main):020:1> end
NoMethodError: undefined method `set_schema' for Task:Class
from (irb):7
irb(main):021:0> class Task < Sequel::Model
irb(main):022:1> plugin :schema
irb(main):023:1> set_schema do
irb(main):024:2* primary_key :id
irb(main):025:2>
irb(main):026:2* varchar :title, :unique => true, :empty => false
irb(main):027:2> boolean :done, :default => false
irb(main):028:2> end
irb(main):029:1>
irb(main):030:1* create_table unless table_exists?
irb(main):031:1>
irb(main):032:1* if empty?
irb(main):033:2> create :title => 'Laundry'
irb(main):034:2> create :title => 'Wash dishes'
irb(main):035:2> end
irb(main):036:1> end
=> #<Task #values={:title=>"Wash dishes", :done=>false, :id=>2}>
irb(main):037:0>

Resources