How do I use rails runner with the Gemfile in /var/www/discourse

AI-generated summary

The user is trying to run a Ruby script using rails r in a Discourse environment to import data from an SQLite3 database into Discourse. The script fails with a LoadError for the sqlite3 gem, even though it’s listed in the Gemfile. Attempts to resolve this by using bundle exec or IMPORT=1 result in errors related to Gemfile changes and deployment mode. The user is confused because they haven’t modified the Gemfile and is unsure why the sqlite3 gem isn’t loading. They also question whether the default SQLite3 setup in Rails has been disabled in Discourse and consider using the SQLite binary directly as an alternative. Chris_Dawson Chris_Dawson

I’ve got a script that needs to load some data from a sqlite3 and then import into discourse.

rails runner

I assumed I could use something like this in /shared/add_in_reverse.rb:

require "sqlite3"

# Open a database
db = SQLite3::Database.new "sqlite3.db"

k = 1234
db.execute( "SELECT * from foo where id = ?'", [ k ] ) do |row|
   puts row
end

title = "hello there"
u = User.find_or_create_by(username: "mexample") do |user|
   user.email = "me@example.com"
end
c = Category.find_or_create_by(name: "Something by mexample") do |category|
   category.user = u
end
Topic.create!( title: title, category: c, user: u )

And, then run it with:

rails r /shared/my_custom_script.rb

But, this fails with cannot load such file -- sqlite3 (LoadError)

bundler: failed to load command: script/rails (script/rails)
<internal:/usr/local/lib/ruby/site_ruby/3.2.0/rubygems/core_ext/kernel_require.rb>:38:in `require': cannot load such file -- sqlite3 (LoadError)
        from <internal:/usr/local/lib/ruby/site_ruby/3.2.0/rubygems/core_ext/kernel_require.rb>:38:in `require'
        from /var/www/discourse/vendor/bundle/ruby/3.2.0/gems/bootsnap-1.17.0/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:17:in `require'
        from /var/www/discourse/vendor/bundle/ruby/3.2.0/gems/zeitwerk-2.6.12/lib/zeitwerk/kernel.rb:38:in `require'
   

Gemfile and bundle exec?

I recalled ruby sometimes needs to use Gemfiles? So, I thought if I was in the /var/www/discourse directory I could prepend bundle exec. But, that fails:

#  bundle exec rails r /shared/add_in_reverse.rb
fatal: detected dubious ownership in repository at '/var/www/discourse'
To add an exception for this directory, call:

        git config --global --add safe.directory /var/www/discourse
/var/www/discourse/vendor/bundle/ruby/3.2.0/gems/activerecord-7.0.7/lib/active_record/connection_adapters/postgresql_adapter.rb:81:in `rescue in new_client': We could not find your database: discourse. Which can be found in the database configuration file located at config/database.yml. (ActiveRecord::NoDatabaseError)

To resolve this issue:

- Did you create the database for this app, or delete it? You may need to create your database.
- Has the database name changed? Check your database.yml config has the correct database name.
...

IMPORT=1

Ok. I saw some examples with IMPORT=1. Do I need that?

IMPORT=1 rails r /shared/add_in_reverse.rb
You are trying to install in deployment mode after changing
your Gemfile. Run `bundle install` elsewhere and add the
updated Gemfile.lock to version control.

If this is a development machine, remove the /var/www/discourse/Gemfile freeze 
by running `bundle config unset deployment`.

The list of sources changed
The dependencies in your gemfile changed

You have added to the Gemfile:
* mysql2
* redcarpet
* sqlite3 (~> 1.3, >= 1.3.13)
* ruby-bbcode-to-md
* reverse_markdown
* tiny_tds
* csv
* parallel
# IMPORT=1 bundle exec rails r /shared/add_in_reverse.rb
You are trying to install in deployment mode after changing
your Gemfile. Run `bundle install` elsewhere and add the
updated Gemfile.lock to version control.

If this is a development machine, remove the /var/www/discourse/Gemfile freeze 
by running `bundle config unset deployment`.

The list of sources changed
The dependencies in your gemfile changed

You have added to the Gemfile:
* mysql2
* redcarpet
* sqlite3 (~> 1.3, >= 1.3.13)
* ruby-bbcode-to-md
* reverse_markdown
* tiny_tds
* csv
* parallel

I didn’t modify the Gemfile at all; I just want to use the sqlite specified in that Gemfile.

Why two rails/ruby?

Is the issue that the one in the path is wrong, and I should use the vendored ruby? I see a bunch of rubies and rails. But using the vendored one does not work (or I don’t know how to use it correctly).

# which ruby
/usr/local/bin/ruby
# which rails
/usr/local/bin/rails
# find /var/www/discourse/ | grep ruby | grep vendor | grep bin | grep rails
/var/www/discourse/vendor/bundle/ruby/3.2.0/bin/rails

# /var/www/discourse/vendor/bundle/ruby/3.2.0/bin/rails runner /shared/add_in_reverse.rb
/usr/local/lib/ruby/site_ruby/3.2.0/rubygems.rb:264:in `find_spec_for_exe': can't find gem railties (>= 0.a) with executable rails (Gem::GemNotFoundException)
        from /usr/local/lib/ruby/site_ruby/3.2.0/rubygems.rb:283:in `activate_bin_path'
        from /var/www/discourse/vendor/bundle/ruby/3.2.0/bin/rails:25:in `<main>'

I guess I can just use backticks with the sqlite binary? I’m only getting a single row afterall. But, I’m mystified why what I’m trying to do isn’t easy, I thought sqlite was the default db for all new rails projects. Did it get disabled intentionally for discourse?