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
$