Railsとデータ操作
モチベーション
- データのコントロールを規則的に実施したい。
- Railsを使ったデータ操作メインにまとまった資料をあまり目にしない。Railsって、そういう用途じゃないからな。でも最終的にやってることは、一緒なので、操作についてまとめる。
- Rails使ってまでやることかと言われると、そこまでじゃないけど、自分で足回り書くのもめんどいし、楽しいじゃんというところ。
- 爆速で、データベースにデータをぶち込んで、データ操作したいなど。
ストラテジー
Rails特にrails consoleを使って、Rubyを書いてデータ操作する。ほぼActive Record。
作成するモデル・使い方
Webページを扱う。モデルは以下の内容で作成する。
| column1* | column2 | column3 | column4 |
|---|---|---|---|
| url | title | access_flag | content |
プロジェクトの作り方
# make dir
mkdir bookmark
cd $_
bundle init
# Install Rails
echo 'gem "rails"' >> Gemfile
# install rails
bundle install
# make rails project
bundle exec rails new --minimal .
Reference
scaffoldを使用した機能作り
| Name | Item |
|---|---|
| モデル名 | Page |
| カラム1* | url:string |
| カラム2 | title:string |
| カラム3 | access_flag:boolean |
| カラム4 | content:text |
rails generate scaffold 名前 [カラム名:型[:index]..] [オプション]
bundle exec rails g scaffold Page url:string title:string access_flag:boolean content:text
Rails 8系を想定している場合、scaffold時にurl:string:uniqと指定すればマイグレーションファイルに自動でユニーク制約が追加される。
実際のところ、scaffoldする必要もないかもしれない。モデルだけ作ればいいかもしれない。
ユニーク制約
migrateファイルにて
生成されるdb/migrate/yyyymmddhhmmss_create_pages.rbを編集する。
add_index :pages, :url, unique: true
をchangeメソッドの中に追加する。制約があれば、自由に追加する。
マイグレートする。
bundle exec rails db:migrate
Reference
Rails scaffoldとは何か? #初心者 - Qiita
データ取り込み
データの用意
データを用意する。今回は、複数のURLを使用する。
cat <<'EOF'> urls.txt
https://yumayx.github.io/works/
https://github.com/YumaYX
https://yumayx.github.io/YS1/
EOF
bundle exec rails consoleにて、追加していく。
File.foreach("urls.txt") do |line|
url = line.strip
next if url.blank?
page = Page.new(url: url)
unless page.save
puts "NG: #{url} / #{page.errors.full_messages}"
end
end
Page.all
rakeタスクにしてもいい。seedを使うのもどうかな。
データ操作
rails console
簡単な操作を行う場合。bundle exec rails consoleにて、例えばタイトルを全て大文字にする。
Page.find_each do |page|
next unless page.title.present?
page.update(title: page.title.upcase)
end
Reference
Active Record クエリインターフェイス - Railsガイド
タスクで扱う場合
少し複雑な操作、何度も繰り返す場合。URLにアクセスして、タイトルを取得する。
bundle exec rails generate task update_titles
vim lib/tasks/update_titles.rake
# lib/tasks/update_titles.rake
namespace :data do
desc "Update titles from URLs"
task update_titles: :environment do
require 'open-uri'
require 'nokogiri'
Page.find_each do |page|
next unless page.url.present?
begin
html = URI.open(page.url, read_timeout: 5)
doc = Nokogiri::HTML(html)
title = doc.at('title')&.text
if title.present?
page.update(title: title)
puts "Updated: #{page.url}"
else
puts "No title: #{page.url}"
end
rescue => e
puts "Error: #{page.url} (#{e.message})"
end
end
end
end
bundle exec rake data:update_titles
保存時に加工したい場合(DBに保存される値を変える)
# example
class User < ApplicationRecord
before_save :normalize_name
private
def normalize_name
self.name = name.strip.capitalize
end
end
データを見たい
アクセス方法
bundle exec rails server
# rails server -b 0.0.0.0
http://localhost:3000/pagesにアクセスする。ドメイン名は適宜変更する。
見た目(html構成)を変えたい
データを扱いたいだけなので、あんまり見たいということは無いが、デバッグ用に。他に、htmlやmarkdown生成には、役立つかもしれない。
この辺りを変えてあげればいいのかも。
app/views/pages/_form.html.erb
app/views/pages/_page.html.erb
app/views/pages/edit.html.erb
app/views/pages/index.html.erb
app/views/pages/new.html.erb
app/views/pages/show.html.erb
_始まりは、他のビューから呼ばれる部品。<%= render 'page' %>などで使用できる。
データが多い場合は表示を絞ったり、した方がいい。
出力・応用
タスクに登録したり、bundle exec rails consoleで、Rubyでできることは、なんでもできる。
Environments
$ ruby -v
ruby 4.0.0 (2025-12-25 revision 553f1675f3) +PRISM [x86_64-linux]
$
$ bundle exec rails -v
Rails 8.1.3
$