Ruby Sequel SQLite3 应用程序将有效对象保存到具有 NULL 属性的数据库
Ruby Sequel SQLite3 app saves valid objects to database with NULL attributes
我在我的应用程序上创建新对象时遇到问题。显然,数据在我的 Sequel::Model 和数据库 table 本身之间的某处丢失,导致条目的 ID 和所有属性均为 NULL。
这是我的模型:
class Wallet < Sequel::Model(:wallets)
attr_accessor :address, :balance
def validate
super
errors.add(:address, "Address can't be empty") if address.empty?
errors.add(:address, "Input address already exists in the db") unless Wallet.where(address: address).empty?
end
end
这是创建它的迁移 table:
Sequel.migration do
change do
create_table(:wallets) do
primary_key :id, unique: true
String :address
Integer :balance
end
end
end
我正在使用 roda 框架。这里是 wallet_app.rb,创建 Wallet 对象的地方:
require 'roda'
require 'sequel'
require 'json'
DB = Sequel.connect('sqlite://database.sqlite3')
class WalletApp < Roda
require './lib/services/balance_service'
require './models/account'
route do |r|
...
r.post "wallets" do
address = r.params["address"]
balance = BalanceService.get_balance(address)
wallet = Wallet.new(address: address, balance: balance)
# Until here we have the attributes correctly set on wallet object
if wallet.valid? && wallet.save
# Now wallet is persisted in the db with an id but address and balance NULL
wallet.to_json
else
wallet.errors.to_json
end
end
end
end
正如上面 class 中的评论所指出的,对象在插入数据库之前是有效的,并且属性设置正确。尽管如此,数据仍保留为所有属性 NULL。我假设迁移或模型定义中有错误,但我找不到任何错误。
如果有帮助,我也将我的 Gemfile 复制到这里:
source "https://rubygems.org"
ruby '2.1.2'
gem 'roda'
gem 'sequel'
gem 'sqlite3'
gem 'httparty'
提前致谢
我习惯了 ActiveRecord 和 Rails,但根据 Sequel documentation 你可以使用 validation_helpers plugin
:
# model
class Wallet < Sequel::Model
# plugin :validation_helpers
def validate
super
validates_presence [:address, :balance], allow_nil: false
validates_unique :address
end
end
您最终可以在迁移中的地址列上设置唯一性约束,而不是在模型中进行唯一性验证。
这种方法应该可以防止自定义验证的一些副作用(尽管你的似乎不是假的)
您应该删除 attr_accessor :address, :balance
,那是破坏性的东西。 Sequel::Model 将属性存储在 values
散列中,而不是作为单独的实例变量。
我在我的应用程序上创建新对象时遇到问题。显然,数据在我的 Sequel::Model 和数据库 table 本身之间的某处丢失,导致条目的 ID 和所有属性均为 NULL。
这是我的模型:
class Wallet < Sequel::Model(:wallets)
attr_accessor :address, :balance
def validate
super
errors.add(:address, "Address can't be empty") if address.empty?
errors.add(:address, "Input address already exists in the db") unless Wallet.where(address: address).empty?
end
end
这是创建它的迁移 table:
Sequel.migration do
change do
create_table(:wallets) do
primary_key :id, unique: true
String :address
Integer :balance
end
end
end
我正在使用 roda 框架。这里是 wallet_app.rb,创建 Wallet 对象的地方:
require 'roda'
require 'sequel'
require 'json'
DB = Sequel.connect('sqlite://database.sqlite3')
class WalletApp < Roda
require './lib/services/balance_service'
require './models/account'
route do |r|
...
r.post "wallets" do
address = r.params["address"]
balance = BalanceService.get_balance(address)
wallet = Wallet.new(address: address, balance: balance)
# Until here we have the attributes correctly set on wallet object
if wallet.valid? && wallet.save
# Now wallet is persisted in the db with an id but address and balance NULL
wallet.to_json
else
wallet.errors.to_json
end
end
end
end
正如上面 class 中的评论所指出的,对象在插入数据库之前是有效的,并且属性设置正确。尽管如此,数据仍保留为所有属性 NULL。我假设迁移或模型定义中有错误,但我找不到任何错误。
如果有帮助,我也将我的 Gemfile 复制到这里:
source "https://rubygems.org"
ruby '2.1.2'
gem 'roda'
gem 'sequel'
gem 'sqlite3'
gem 'httparty'
提前致谢
我习惯了 ActiveRecord 和 Rails,但根据 Sequel documentation 你可以使用 validation_helpers plugin
:
# model
class Wallet < Sequel::Model
# plugin :validation_helpers
def validate
super
validates_presence [:address, :balance], allow_nil: false
validates_unique :address
end
end
您最终可以在迁移中的地址列上设置唯一性约束,而不是在模型中进行唯一性验证。 这种方法应该可以防止自定义验证的一些副作用(尽管你的似乎不是假的)
您应该删除 attr_accessor :address, :balance
,那是破坏性的东西。 Sequel::Model 将属性存储在 values
散列中,而不是作为单独的实例变量。