RACCOON TECH BLOG

株式会社ラクーンホールディングス 技術戦略部より、
tipsやノウハウなど技術的な話題を
発信いたします。

LaravelとRailsの機能を比較!ルーティング・ORM・DIなどをまとめてみました

こんにちは!開発チームのさいとーです。

近年、PHPのフレームワーク界隈では「Laravel」が盛り上がっていますね。
ラクーンではLaravelを使用したサービスの開発は行ってはいないのですが、
今後の開発の選択肢の1つとして挙げられるようにと、一通りの機能をリサーチしました。

「Ruby on Rails」(以下Rails)と似ているとは聞いていたのですが、実際使ってみると本当に似ていました。
一方で、言語仕様や思想の違いから異なる部分も見えてきました。

ということで今回は「Laravel」と「Rails」を機能毎に比較し、似ている部分、異なる部分をまとめてみました!
※Laravel5.7 と Rails5.2.2 を比較しています。

ルーティング編

まずはルーティングです。

ルーティングの記述

Laravel

<?php
Route::get('/', 'HogeController@fuga');

Rails

Rails.application.routes.draw do
  get '/', to: 'hoge#fuga'
end

これは、'/'にgetでアクセスが来たときに、hogeコントローラーのfugaメソッドを実行するという処理になります。

片方を知っていたら、もう片方も理解できるような記述ですよね?

getの他にpost,put,patch,deleteなど指定でき、RESTルーティングが一気に定義できる「resource」もLaravel、Rails共に使えます。

ORM編

次にORMです。

それぞれORMフレームワークには、Laravelは「Eloquent」、Railsは「ActiveRecord」という名称がつけられています。
どちらもActive Recordパターンを実装したORMです。

基本的にはModelクラスを生成し、そのModelクラスを使ってメソッドを実行することでCRUD操作ができます。
Modelの生成からCRUDの基本操作まで、簡単に見てみましょう!

Modelの生成

どちらもModelは基本的にコマンドで生成します。(コマンドについては後述します)
ここでは生成された初期状態のModelの定義を見てみます。
※usersというテーブルに紐づくUserモデルを例にしています。
Laravel

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class User extends Model
{
    //
}

Rails

class User < ApplicationRecord
end

言語仕様による記述量の違いはありますが、基本的にこれだけでテーブルのCRUD操作が出来てしまいます。

操作の例を以下に記述します。

Laravel Rails
create $user = new User;
$user->name = 'saito;
$user->save();
user = User.new
user.name = 'saito'
user.save
read $users = User::all();
$user = User::find(1);
users = User.all
user = User.find(1)
update $user = User::find(1);
$user->name = 'tanaka;
$user->save();
user = User.find(1)
user.name = 'tanaka'
user.save
delete $user = User::find(1);
$user->delete();
user = User.find(1)
user.destroy

非常に似ていますね。
他にもたくさん書き方はありますが、大体は同じような書き方ができると思います。

このあたりの機能の違いとしては、Laravelには論理削除機能が標準搭載されているということでしょうか。
Railsではgemを入れれば実現はできます。
標準搭載ということはLaravelのバージョンアップによって不意に機能が使えなくなるという事態が起きにくいので、
使う側からすると安心がありますよね。

マイグレーション編

マイグレーションはデータベーススキーマを管理するためのDSLですが、こちらもLaravel、Rails両方に実装されています。

作成や実行はコマンドで行うので、コマンド編で比較します。
ここでは、マイグレーションファイルの中身を見てみましょう。

マイグレーションファイル

先ほどのORM編で扱ったUserモデルと紐づいている、userテーブルを作成するマイグレーションを
Laravel、Railsでそれぞれ記述してみます。
userテーブルの定義は以下とします。
※mysqlでの定義とします

userテーブル定義

カラム名 データ型 NULL Key Default 属性
id int NO PRI NULL auto_increment
name varchar NO NULL
email varchar NO NULL unique
password varchar NO NULL
comment text YES NULL
create_at timestamp NO NULL

上記usersテーブルを作成する際の、それぞれのマイグレーションファイルは以下のようになります。

Laravel

<?php

use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class CreateUsersTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('users', function (Blueprint $table) {
            $table->increments('id');
            $table->string('name');
            $table->string('email')->unique();
            $table->string('password');
            $table->text('comment')->nullable();
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('users');
    }
}

Rails

class CreateUsers < ActiveRecord::Migration[5.2]
  def change
    create_table :users do |t|
      t.string :name, null: false
      t.string :email, unique: true, null: false
      t.string :password, null: false
      t.text :comment
      t.timestamps null: false
    end
  end
end

テーブル作成のマイグレーションファイルをコマンド作成すると、
Railsはchangeメソッドがデフォルトで記述されたものが生成され、
Laravelはupメソッドとdownメソッドがデフォルト記述されたものが生成されます。
とはいえ、Railsにもupメソッドとdownメソッドを記述する場合もあり、Laravelのup,downはそれと同じような動作をします。

記述方法はパッと見で似ていますね。

細かい違いですが、
Laravelはプライマリーキーになる'id'カラムの定義を記述しているのに対し、Railsは何も記述していなくても、'id'カラムが作成されます。
Laravelではマイグレーションファイルを生成した時点で'id'は既に定義されているので、スタート地点は同じっちゃ同じですが。
※ちなみに、これらをmigrateすると、Laravelの'id'は「int(10) unsigned」となり、Railsの'id'は「bigint(20)」となるので、実は同じテーブルにはなりません。これらを対象に外部キー制約を付けるときなどは気をつけましょう。

また、LaravelはデフォルトでNOT NULL制約がつくので、NULLを許可するカラムに「nullable()」を付けるのに対し、
Railsは「null: false」を付けたものにNOT NULL制約が定義されるという違いもあります。

DI編

LaravelにはDIの機能が用意されていますが、RailsにはDIの機能は用意されていません。(もちろん自前で実装は可能です)

LaravelのDI機能の使い方を簡単に説明をすると、下記の通りです。

今回のテーマは”比較”なので、詳しい説明は省かせてください。

まとめると

Laravel Rails
サービスプロバイダ、サービスコンテナを
を用いて実装
機能なし

となります。

Validation編

LaravelとRailsのバリデーションは結構違います。
何が違うって、まず推奨されている実行タイミングが違います。

バリデーションの記述場所や行うタイミング

Laravel Rails
記述場所 Controller(FormRequest) Model
推奨実行タイミング Controllerのメソッド内任意 Modelのcreateやsave,updateの実行時

あくまで推奨実行タイミングなので、実際はどこでバリデーションをしてもいいのですが、
フレームワークとしては、上記表の箇所で実行した方が見た目がスッキリしそうですね。

Laravelの記述場所になっている「FormRequest」ですが、
これを使うとControllerのメソッドに入ったタイミングで既にバリデーションが終わっているという優れものです。
Controllerでバリデーションを行いたくない場合は、FormRequestを使用することをお勧めします。

コード

記述する場所が違うので、コードの見た目も違います。
下記バリデーションを実装するコードを実際に見てみましょう。

バリデーション定義

項目名 バリデーション
name 必須,100文字以下
email 必須,100文字以下,メール形式,usersテーブルのemailカラムに同じ値が存在しない
password 必須,6文字以上, 12文字以下

Laravel

<?php

namespace App\Http\Requests;

use Illuminate\Foundation\Http\FormRequest;

class UserRequest extends FormRequest
{
    public function authorize()
    {
        return true;
    }

    public function rules()
    {
        return [
            'name' => ['required', 'max:100'],
            'email' => ['required', 'max:100', 'email', unique:users],
            'password' => ['required', 'min:6', 'max:12'],
        ];
    }
}

Rails

class User < ApplicationRecord
    VALID_EMAIL_REGEX = /\A[\w+\-.]+@[a-z\d\-.]+\.[a-z]+\z/i

    validates :name, presence: true, length: { maximum: 100 }
    validates :email, presence: true, length: { maximum: 100 }, format: { with: VALID_EMAIL_REGEX }, uniqueness: true
    validates :password, presence: true, length: { in: 6..12 }
end

見た目は違えど、記述量はそこまで変わらないようです。
Laravelはメールアドレスの形式チェックが最初から用意されているように、
バリデーションの種類が豊富なので、なかなか使いやすい印象でした。

コマンド編

LaravelもRailsも、様々な操作をコマンドで行います。

各操作毎にコマンドをまとめてみました。

操作 Laravel Rails
ルート確認 php artisan route:list rails routes
Controller作成 php artisan make:controller コントローラー名 rails generate controller コントローラー名
Model作成 php artisan make:model モデル名 rails generate model モデル名
マイグレーションファイル作成 php artisan make:migration マイグレーションファイル名 rails generate migration マイグレーションファイル名
マイグレーション実行 php artisan migrate rails db:migrate
シーディング実行 php artisan db:seed rails db:seed
サーバ起動 php artisan serve rails server
REPL php artisan tinker rails console

多少の違いはあれど、やっぱり似ていますね。

LaravelにはあってRailsにはない、サービスプロバイダやフォームリクエストもコマンドで生成します。

操作 Laravel
サービスプロバイダ作成 php artisan make:provider サービスプロバイダ名
FormRequest作成 php artisan make:request フォームリクエスト名

基本は同じようなコマンドになっているので、何のコマンドなのか想像しやすいですね。

まとめ

LaravelとRailsの基本的な機能を比較してみましたが、記述の仕方などを含め驚くほど似ていましたね。

こうして同じ動作をするコードを並べててみると、Railsの方がコード量が少なく記述的には簡単そうかなという印象を受けましたが、
実際はコマンド生成でひな形は出来上がるので、小さめのアプリケーションならそこまで差はなさそうです。

また、Laravelは今回紹介した機能以外にも、認証系(ユーザ登録/ログイン/ログアウト/パスワード再設定)の機能や、ページネーションを備えており、Railsと比べると、フレームワーク自体に備わっている機能は多いように感じました。

今後ラクーンでLaravelを使った開発が行われるかはわかりませんが、
Homestead(Laravel公式のvagrant box)などを使用すれば、簡単に開発環境の構築ができますので、
一度使ってみてはいかがでしょうか?

関連記事

運営会社:株式会社ラクーンホールディングス(c)2000 RACCOON HOLDINGS, Inc