Skip to content

feat: allow users to have an associated barcode - #151

Merged
YtvwlD merged 2 commits into
chaosdorf:mainfrom
thexyno:user-barcodes
Jan 23, 2026
Merged

YtvwlD merged 2 commits into
chaosdorf:mainfrom
thexyno:user-barcodes

Conversation

@thexyno

@thexyno thexyno commented Dec 28, 2025

Copy link
Copy Markdown
Contributor

This PR allows users to have an optional personal barcode so that they can quickly open their page using a [library card, iButton, nfc implant]. lucy hasn't done anything with rails before so it's sorry if this code is bad.

image image

@YtvwlD YtvwlD left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All in all this look pretty good!

Just two things:

  • A user can only have a single barcode. Is this correct?
  • The null: true in the migrations breaks on sqlite. Can we remove this?

@thexyno

thexyno commented Dec 29, 2025

Copy link
Copy Markdown
Contributor Author
* A user can only have a single barcode. Is this correct?

yes, that was the simplest to implement. it can change that to multiple tho if you think that'd be practical

* The `null: true` in the migrations breaks on sqlite. Can we remove this?

do they? bin/rails db:drop && bin/rails db:migrate didn't throw any errors for this one.

@YtvwlD

YtvwlD commented Dec 29, 2025

Copy link
Copy Markdown
Member

This really depends on the use-case (which I don't really know). I'm fine with a single barcode per account; we could even change this later.


This is the error I got when migrating an existing dev setup:

> bundle exec rake db:migrate
== 20251228140735 AddBarcodeToUser: migrating =================================
-- add_column(:users, :barcode, :string, {:null=>true})
   -> 0.0030s
-- add_index(:users, :barcode, {:unique=>true, :null=>true})
rake aborted!
StandardError: An error has occurred, this and all later migrations canceled: (StandardError)

Unknown key: :null. Valid keys are: :unique, :length, :order, :opclass, :where, :type, :using, :comment, :algorithm, :include, :nulls_not_distinct
/home/ubuntu/dev/mete/vendor/bundle/ruby/3.2.0/gems/activesupport-8.0.2.1/lib/active_support/core_ext/hash/keys.rb:52:in `block in assert_valid_keys'
/home/ubuntu/dev/mete/vendor/bundle/ruby/3.2.0/gems/activesupport-8.0.2.1/lib/active_support/core_ext/hash/keys.rb:50:in `each_key'
/home/ubuntu/dev/mete/vendor/bundle/ruby/3.2.0/gems/activesupport-8.0.2.1/lib/active_support/core_ext/hash/keys.rb:50:in `assert_valid_keys'
/home/ubuntu/dev/mete/vendor/bundle/ruby/3.2.0/gems/activerecord-8.0.2.1/lib/active_record/connection_adapters/abstract/schema_statements.rb:1477:in `add_index_options'
/home/ubuntu/dev/mete/vendor/bundle/ruby/3.2.0/gems/activerecord-8.0.2.1/lib/active_record/connection_adapters/abstract/schema_statements.rb:926:in `build_create_index_definition'
/home/ubuntu/dev/mete/vendor/bundle/ruby/3.2.0/gems/activerecord-8.0.2.1/lib/active_record/connection_adapters/abstract/schema_statements.rb:916:in `add_index'
/home/ubuntu/dev/mete/vendor/bundle/ruby/3.2.0/gems/activerecord-8.0.2.1/lib/active_record/migration/default_strategy.rb:10:in `method_missing'
/home/ubuntu/dev/mete/vendor/bundle/ruby/3.2.0/gems/activerecord-8.0.2.1/lib/active_record/migration.rb:1056:in `block in method_missing'
/home/ubuntu/dev/mete/vendor/bundle/ruby/3.2.0/gems/activerecord-8.0.2.1/lib/active_record/migration.rb:1022:in `block in say_with_time'
/home/ubuntu/dev/mete/vendor/bundle/ruby/3.2.0/gems/activesupport-8.0.2.1/lib/active_support/benchmark.rb:17:in `realtime'
/home/ubuntu/dev/mete/vendor/bundle/ruby/3.2.0/gems/activerecord-8.0.2.1/lib/active_record/migration.rb:1022:in `say_with_time'
/home/ubuntu/dev/mete/vendor/bundle/ruby/3.2.0/gems/activerecord-8.0.2.1/lib/active_record/migration.rb:1045:in `method_missing'
/home/ubuntu/dev/mete/db/migrate/20251228140735_add_barcode_to_user.rb:4:in `change'
/home/ubuntu/dev/mete/vendor/bundle/ruby/3.2.0/gems/activerecord-8.0.2.1/lib/active_record/migration.rb:991:in `exec_migration'
/home/ubuntu/dev/mete/vendor/bundle/ruby/3.2.0/gems/activerecord-8.0.2.1/lib/active_record/migration.rb:975:in `block (2 levels) in migrate'
/home/ubuntu/dev/mete/vendor/bundle/ruby/3.2.0/gems/activesupport-8.0.2.1/lib/active_support/benchmark.rb:17:in `realtime'
/home/ubuntu/dev/mete/vendor/bundle/ruby/3.2.0/gems/activerecord-8.0.2.1/lib/active_record/migration.rb:974:in `block in migrate'
/home/ubuntu/dev/mete/vendor/bundle/ruby/3.2.0/gems/activerecord-8.0.2.1/lib/active_record/connection_adapters/abstract/connection_pool.rb:412:in `with_connection'
/home/ubuntu/dev/mete/vendor/bundle/ruby/3.2.0/gems/activerecord-8.0.2.1/lib/active_record/migration.rb:973:in `migrate'
/home/ubuntu/dev/mete/vendor/bundle/ruby/3.2.0/gems/activerecord-8.0.2.1/lib/active_record/migration.rb:1187:in `migrate'
/home/ubuntu/dev/mete/vendor/bundle/ruby/3.2.0/gems/activerecord-8.0.2.1/lib/active_record/migration.rb:1535:in `block in execute_migration_in_transaction'
/home/ubuntu/dev/mete/vendor/bundle/ruby/3.2.0/gems/activerecord-8.0.2.1/lib/active_record/connection_adapters/abstract/transaction.rb:626:in `block in within_new_transaction'
/home/ubuntu/dev/mete/vendor/bundle/ruby/3.2.0/gems/activesupport-8.0.2.1/lib/active_support/concurrency/null_lock.rb:9:in `synchronize'
/home/ubuntu/dev/mete/vendor/bundle/ruby/3.2.0/gems/activerecord-8.0.2.1/lib/active_record/connection_adapters/abstract/transaction.rb:623:in `within_new_transaction'
/home/ubuntu/dev/mete/vendor/bundle/ruby/3.2.0/gems/activerecord-8.0.2.1/lib/active_record/connection_adapters/abstract/database_statements.rb:367:in `within_new_transaction'
/home/ubuntu/dev/mete/vendor/bundle/ruby/3.2.0/gems/activerecord-8.0.2.1/lib/active_record/connection_adapters/abstract/database_statements.rb:359:in `transaction'
/home/ubuntu/dev/mete/vendor/bundle/ruby/3.2.0/gems/activerecord-8.0.2.1/lib/active_record/migration.rb:1586:in `ddl_transaction'
/home/ubuntu/dev/mete/vendor/bundle/ruby/3.2.0/gems/activerecord-8.0.2.1/lib/active_record/migration.rb:1534:in `execute_migration_in_transaction'
/home/ubuntu/dev/mete/vendor/bundle/ruby/3.2.0/gems/activerecord-8.0.2.1/lib/active_record/migration.rb:1509:in `each'
/home/ubuntu/dev/mete/vendor/bundle/ruby/3.2.0/gems/activerecord-8.0.2.1/lib/active_record/migration.rb:1509:in `migrate_without_lock'
/home/ubuntu/dev/mete/vendor/bundle/ruby/3.2.0/gems/activerecord-8.0.2.1/lib/active_record/migration.rb:1456:in `migrate'
/home/ubuntu/dev/mete/vendor/bundle/ruby/3.2.0/gems/activerecord-8.0.2.1/lib/active_record/migration.rb:1261:in `up'
/home/ubuntu/dev/mete/vendor/bundle/ruby/3.2.0/gems/activerecord-8.0.2.1/lib/active_record/migration.rb:1236:in `migrate'
/home/ubuntu/dev/mete/vendor/bundle/ruby/3.2.0/gems/activerecord-8.0.2.1/lib/active_record/tasks/database_tasks.rb:270:in `migrate'
/home/ubuntu/dev/mete/vendor/bundle/ruby/3.2.0/gems/activerecord-8.0.2.1/lib/active_record/tasks/database_tasks.rb:248:in `migrate_all'
/home/ubuntu/dev/mete/vendor/bundle/ruby/3.2.0/gems/activerecord-8.0.2.1/lib/active_record/railties/databases.rake:90:in `block (2 levels) in <main>'
/home/ubuntu/dev/mete/vendor/bundle/ruby/3.2.0/gems/rake-13.3.0/exe/rake:27:in `<top (required)>'

Caused by:
ArgumentError: Unknown key: :null. Valid keys are: :unique, :length, :order, :opclass, :where, :type, :using, :comment, :algorithm, :include, :nulls_not_distinct (ArgumentError)

        raise ArgumentError.new("Unknown key: #{k.inspect}. Valid keys are: #{valid_keys.map(&:inspect).join(', ')}")
              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
/home/ubuntu/dev/mete/vendor/bundle/ruby/3.2.0/gems/activesupport-8.0.2.1/lib/active_support/core_ext/hash/keys.rb:52:in `block in assert_valid_keys'
/home/ubuntu/dev/mete/vendor/bundle/ruby/3.2.0/gems/activesupport-8.0.2.1/lib/active_support/core_ext/hash/keys.rb:50:in `each_key'
/home/ubuntu/dev/mete/vendor/bundle/ruby/3.2.0/gems/activesupport-8.0.2.1/lib/active_support/core_ext/hash/keys.rb:50:in `assert_valid_keys'
/home/ubuntu/dev/mete/vendor/bundle/ruby/3.2.0/gems/activerecord-8.0.2.1/lib/active_record/connection_adapters/abstract/schema_statements.rb:1477:in `add_index_options'
/home/ubuntu/dev/mete/vendor/bundle/ruby/3.2.0/gems/activerecord-8.0.2.1/lib/active_record/connection_adapters/abstract/schema_statements.rb:926:in `build_create_index_definition'
/home/ubuntu/dev/mete/vendor/bundle/ruby/3.2.0/gems/activerecord-8.0.2.1/lib/active_record/connection_adapters/abstract/schema_statements.rb:916:in `add_index'
/home/ubuntu/dev/mete/vendor/bundle/ruby/3.2.0/gems/activerecord-8.0.2.1/lib/active_record/migration/default_strategy.rb:10:in `method_missing'
/home/ubuntu/dev/mete/vendor/bundle/ruby/3.2.0/gems/activerecord-8.0.2.1/lib/active_record/migration.rb:1056:in `block in method_missing'
/home/ubuntu/dev/mete/vendor/bundle/ruby/3.2.0/gems/activerecord-8.0.2.1/lib/active_record/migration.rb:1022:in `block in say_with_time'
/home/ubuntu/dev/mete/vendor/bundle/ruby/3.2.0/gems/activesupport-8.0.2.1/lib/active_support/benchmark.rb:17:in `realtime'
/home/ubuntu/dev/mete/vendor/bundle/ruby/3.2.0/gems/activerecord-8.0.2.1/lib/active_record/migration.rb:1022:in `say_with_time'
/home/ubuntu/dev/mete/vendor/bundle/ruby/3.2.0/gems/activerecord-8.0.2.1/lib/active_record/migration.rb:1045:in `method_missing'
/home/ubuntu/dev/mete/db/migrate/20251228140735_add_barcode_to_user.rb:4:in `change'
/home/ubuntu/dev/mete/vendor/bundle/ruby/3.2.0/gems/activerecord-8.0.2.1/lib/active_record/migration.rb:991:in `exec_migration'
/home/ubuntu/dev/mete/vendor/bundle/ruby/3.2.0/gems/activerecord-8.0.2.1/lib/active_record/migration.rb:975:in `block (2 levels) in migrate'
/home/ubuntu/dev/mete/vendor/bundle/ruby/3.2.0/gems/activesupport-8.0.2.1/lib/active_support/benchmark.rb:17:in `realtime'
/home/ubuntu/dev/mete/vendor/bundle/ruby/3.2.0/gems/activerecord-8.0.2.1/lib/active_record/migration.rb:974:in `block in migrate'
/home/ubuntu/dev/mete/vendor/bundle/ruby/3.2.0/gems/activerecord-8.0.2.1/lib/active_record/connection_adapters/abstract/connection_pool.rb:412:in `with_connection'
/home/ubuntu/dev/mete/vendor/bundle/ruby/3.2.0/gems/activerecord-8.0.2.1/lib/active_record/migration.rb:973:in `migrate'
/home/ubuntu/dev/mete/vendor/bundle/ruby/3.2.0/gems/activerecord-8.0.2.1/lib/active_record/migration.rb:1187:in `migrate'
/home/ubuntu/dev/mete/vendor/bundle/ruby/3.2.0/gems/activerecord-8.0.2.1/lib/active_record/migration.rb:1535:in `block in execute_migration_in_transaction'
/home/ubuntu/dev/mete/vendor/bundle/ruby/3.2.0/gems/activerecord-8.0.2.1/lib/active_record/connection_adapters/abstract/transaction.rb:626:in `block in within_new_transaction'
/home/ubuntu/dev/mete/vendor/bundle/ruby/3.2.0/gems/activesupport-8.0.2.1/lib/active_support/concurrency/null_lock.rb:9:in `synchronize'
/home/ubuntu/dev/mete/vendor/bundle/ruby/3.2.0/gems/activerecord-8.0.2.1/lib/active_record/connection_adapters/abstract/transaction.rb:623:in `within_new_transaction'
/home/ubuntu/dev/mete/vendor/bundle/ruby/3.2.0/gems/activerecord-8.0.2.1/lib/active_record/connection_adapters/abstract/database_statements.rb:367:in `within_new_transaction'
/home/ubuntu/dev/mete/vendor/bundle/ruby/3.2.0/gems/activerecord-8.0.2.1/lib/active_record/connection_adapters/abstract/database_statements.rb:359:in `transaction'
/home/ubuntu/dev/mete/vendor/bundle/ruby/3.2.0/gems/activerecord-8.0.2.1/lib/active_record/migration.rb:1586:in `ddl_transaction'
/home/ubuntu/dev/mete/vendor/bundle/ruby/3.2.0/gems/activerecord-8.0.2.1/lib/active_record/migration.rb:1534:in `execute_migration_in_transaction'
/home/ubuntu/dev/mete/vendor/bundle/ruby/3.2.0/gems/activerecord-8.0.2.1/lib/active_record/migration.rb:1509:in `each'
/home/ubuntu/dev/mete/vendor/bundle/ruby/3.2.0/gems/activerecord-8.0.2.1/lib/active_record/migration.rb:1509:in `migrate_without_lock'
/home/ubuntu/dev/mete/vendor/bundle/ruby/3.2.0/gems/activerecord-8.0.2.1/lib/active_record/migration.rb:1456:in `migrate'
/home/ubuntu/dev/mete/vendor/bundle/ruby/3.2.0/gems/activerecord-8.0.2.1/lib/active_record/migration.rb:1261:in `up'
/home/ubuntu/dev/mete/vendor/bundle/ruby/3.2.0/gems/activerecord-8.0.2.1/lib/active_record/migration.rb:1236:in `migrate'
/home/ubuntu/dev/mete/vendor/bundle/ruby/3.2.0/gems/activerecord-8.0.2.1/lib/active_record/tasks/database_tasks.rb:270:in `migrate'
/home/ubuntu/dev/mete/vendor/bundle/ruby/3.2.0/gems/activerecord-8.0.2.1/lib/active_record/tasks/database_tasks.rb:248:in `migrate_all'
/home/ubuntu/dev/mete/vendor/bundle/ruby/3.2.0/gems/activerecord-8.0.2.1/lib/active_record/railties/databases.rake:90:in `block (2 levels) in <main>'
/home/ubuntu/dev/mete/vendor/bundle/ruby/3.2.0/gems/rake-13.3.0/exe/rake:27:in `<top (required)>'
Tasks: TOP => db:migrate
(See full trace by running task with --trace)

I can reproduce this by switching to main, running db:drop and db:migrate, then switching to user-barcodes and running the migrations again. I'm not sure why this works when starting with a nonexistent database.

@thexyno

thexyno commented Dec 29, 2025

Copy link
Copy Markdown
Contributor Author

This really depends on the use-case (which I don't really know). I'm fine with a single barcode per account; we could even change this later.

the main use case this one has is to strap an ibutton/nfc reader to the chaosdorf mete terminal and do faster user selection with that

I can reproduce this by switching to main, running db:drop and db:migrate, then switching to user-barcodes and running the migrations again. I'm not sure why this works when starting with a nonexistent database.

hmm, weird. it removed the null: true

@thexyno
thexyno requested a review from YtvwlD December 29, 2025 21:06
@thexyno

thexyno commented Jan 12, 2026

Copy link
Copy Markdown
Contributor Author

beep

@YtvwlD
YtvwlD merged commit 1e9bab1 into chaosdorf:main Jan 23, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants