Приложение Ruby Sequel SQLite3 сохраняет действительные объекты в базе данных с атрибутами NULL
У меня проблемы с созданием новых объектов в моем приложении. По-видимому, данные теряются где-то между моим Sequel::Model и самой таблицей БД, в результате чего появляются записи с идентификатором и всеми атрибутами в 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
И это миграция, которая создала свою таблицу:
Sequel.migration do
change do
create_table(:wallets) do
primary_key :id, unique: true
String :address
Integer :balance
end
end
end
Я использую роды рамки. Вот 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
Как указано в комментариях к классу выше, объект действителен перед вставкой в БД, и атрибуты отображаются правильно установленными. Тем не менее, данные сохраняются как все атрибуты NULL. Я предполагаю ошибку в переносе или определении модели, но не могу найти ни одной.
В случае, если это помогает, я также копирую свой Gemfile здесь:
source "https://rubygems.org"
ruby '2.1.2'
gem 'roda'
gem 'sequel'
gem 'sqlite3'
gem 'httparty'
заранее спасибо
2 ответа
Вы должны удалить attr_accessor :address, :balance
это то, что ломает вещи. Sequel:: Модель хранит атрибуты в values
хэш, а не как отдельные переменные экземпляра.
Я привык к ActiveRecord и Rails, но в соответствии с документацией Sequel вы можете использовать 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
В конечном итоге вы можете установить уникальное ограничение для столбца адреса в процессе миграции вместо проверки уникальности в модели. Этот метод должен предотвращать некоторые побочные эффекты пользовательских проверок (несмотря на то, что ваши не кажутся поддельными)