Приложение 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

В конечном итоге вы можете установить уникальное ограничение для столбца адреса в процессе миграции вместо проверки уникальности в модели. Этот метод должен предотвращать некоторые побочные эффекты пользовательских проверок (несмотря на то, что ваши не кажутся поддельными)

Другие вопросы по тегам