iTranslated by AI
Trying out roda-sequel-stack
I wonder what web framework would be good if I want to use Sequel instead of ActiveRecord in Ruby. Maybe Hanami. Well, using Sequel with Rails is also an option.
When I tweeted this, the author himself replied:
I recommend Roda+Sequel https://roda.jeremyevans.net
He introduced me to roda-sequel-stack, so I'm going to try it out.
Initial Setup
Copy to local using git clone.
% git clone https://github.com/jeremyevans/roda-sequel-stack.git hoge
% cd hoge
You might want to delete the Git history of roda-sequel-stack itself and create a new repository.
% rm -rf .git
% git init
% git commit --allow-empty -m 'Initial commit'
Set up as the "Hoge" app.
% rake 'setup[Hoge]'
% bundle install
It uses PostgreSQL by default, but I want to use MySQL, so I'll change it.
-gem 'sequel_pg', '>= 1.8', require: 'sequel'
+gem 'ruby-mysql', '>= 4.0', require: 'mysql'
For simplicity, I'll use Docker Compose for MySQL.
services:
db:
image: mysql:8.0.33
ports:
- "127.0.0.1:13306:3306"
volumes:
- db:/var/lib/mysql
environment:
MYSQL_ALLOW_EMPTY_PASSWORD: 'yes'
volumes:
db:
Create the database and user.
% docker-compose up -d
% docker-compose exec db mysql
mysql> create database hoge_production;
mysql> create database hoge_development;
mysql> create database hoge_test;
mysql> create user hoge;
mysql> grant all on `hoge\_%`.* to hoge;
Configure the database connection information.
...
- ENV['HOGE_DATABASE_URL'] ||= "postgres:///hoge_test?user=hoge"
+ ENV['HOGE_DATABASE_URL'] ||= "mysql://hoge@127.0.0.1:13306/hoge_test"
...
- ENV['HOGE_DATABASE_URL'] ||= "postgres:///hoge_production?user=hoge"
+ ENV['HOGE_DATABASE_URL'] ||= "mysql://hoge@127.0.0.1:13306/hoge_production"
...
- ENV['HOGE_DATABASE_URL'] ||= "postgres:///hoge_development?user=hoge"
+ ENV['HOGE_DATABASE_URL'] ||= "mysql://hoge@127.0.0.1:13306/hoge_development"
...
Install rackup and start the service.
% gem install rackup
% rackup -p 8080
If you access http://localhost:8080 in your browser, the following page will be displayed.

Building a typical sample service
Migration
Create the Article model. Delete the sample migration file.
% rm migrate/001_tables.rb
Create a new migration file. For the syntax of Sequel migration files, refer to Sequel's schema_modification.rdoc.
Sequel.migration do
change do
create_table :articles do
primary_key :id
String :title
String :body, size: 1024
end
end
end
Run the migration.
% rake dev_up
Model
Create the Article model.
class Article < Sequel::Model
end
Routing (Controller)
Create the route file. This is like a controller in Rails.
For information on how to write it, see Roda's README.rdoc.
class Hoge
hash_branch('articles') do |r|
r.is do
@articles = Article.all
view 'index'
end
end
end
View
Create the view file. Since it's an erb file, it's mostly the same as a Rails view file.
<table>
<tr>
<th>タイトル</th>
<th>作成日時</th>
</tr>
<% @articles.each do |article| %>
<tr>
<td><%= article.title %></td>
<td><%= article.created_at %></td>
</tr>
<% end %>
</table>
Now, if you access http://localhost:8080/articles in your browser, the list of articles should be displayed, but since there is no data yet, nothing will be shown.

IRB (Console)
Launch irb with rake dev_irb and try creating an Article object. It's similar to Rails' rails console.
% rake dev_irb
irb(main):001:0> Article.create(title: 'ほげほげほげほげ', body: "1行目\n2行目", created_at: Time.now)
It was displayed.

CSS
Let's tweak the CSS to add borders to the table.
th {
border: solid 1px
}
td {
border: solid 1px
}

Links
Let's make it so that you can see the body text by clicking on the title.
- <td><%= article.title %></td>
+ <td><a href="/articles/<%=article.id%>"><%= article.title %></a></td>
Now the title is a link. However, since it's a bit clunky, let's use the link_to plugin.
Configure the path for the Article object.
plugin :link_to
path Article do |article|
"/articles/#{article.id}"
end
Rewrite the view to call the link_to method.
- <td><a href="/articles/<%=article.id%>"><%= article.title %></a></td>
+ <td><%== link_to(article.title, article) %></a></td>
It's become a bit simpler.
To display the body when the link is clicked, modify the route file and create a view file.
class Hoge
hash_branch('articles') do |r|
r.is do
@articles = Article.all
view 'index'
end
r.is Integer do |id|
@article = Article.with_pk!(id)
view "show"
end
end
end
<dl>
<dt>タイトル</dt>
<dd><%= @article.title %></dd>
<dt>作成日時</dt>
<dd><%= @article.created_at %></dd>
<dt>本文</dt>
<textarea readonly><%= @article.body %></textarea>
</dl>

New Registration
Earlier, we created an article record from irb, but now let's create a page where you can register articles from the browser.
<form method="post" action="/articles">
<dl>
<dt>タイトル</dt>
<dd><input type="text" name="title"></dd>
<dt>本文</dt>
<dd><textarea name="body"></textarea></dd>
</dl>
<input type="submit">
</form>
The route file looks like this:
class Hoge
hash_branch('articles') do |r|
r.is do
@articles = Article.all
view "index"
end
r.is Integer do |id|
@article = Article.with_pk!(id)
view "show"
end
r.is 'new' do
view "new"
end
end
end
Now, if you access http://localhost:8080/articles/new, the new registration screen will be displayed.

Modify the route file to accept POST requests.
class Hoge
hash_branch('articles') do |r|
r.is do
r.post do
Article.create(title: r.params['title'], body: r.params['body'], created_at: Time.now)
r.redirect
end
r.get do
@articles = Article.all
view "index"
end
end
r.is Integer do |id|
@article = Article.with_pk!(id)
view "show"
end
r.is 'new' do
view "new"
end
end
end
However, when you actually try to POST, you'll get an error saying "Invalid Security Token".

Add csrf_tag to the view file.
<form method="post" action="/articles">
<dl>
<dt>タイトル</dt>
<dd><input type="text" name="title"></dd>
<dt>本文</dt>
<dd><textarea name="body"></textarea></dd>
</dl>
<%== csrf_tag('/articles') %>
<input type="submit">
</form>
Now you can create new articles.
Conclusion
roda-sequel-stack is not a gem; it's more like a sample for building a full-stack framework using Roda, Sequel, and other libraries, rather than a full-stack framework like Rails.
I've been using Sequel for over 10 years, and Roda seems quite good, so I might even like it more than Rails.
Discussion