🎸

DjangoからRailsを使うようになって

2023/06/21に公開

はじめに

これまで実務ではDjangoを使用して開発してきましたが、転職を機にRuby on Railsを使用することになりました。

「Djangoが使えればRailsも使える」という話をネット上でよく見かけましたが、実際にDjangoに慣れた上でRailsを使用すると、いくつか戸惑う点がありました。

そこで、今回は私が感じたDjangoとRailsの主な違いをいくつか挙げ、主にDjangoで開発しているエンジニアに向けて、Railsでの開発で気をつける点をご紹介したいと思います。

言語の違い

PythonとRubyは両方とも動的型付け言語で、似ている面も多いですが、Pythonと比べたRubyの特徴で、ここは個人的に大きく違うなと思った点を以下に挙げてみます。

メソッド呼び出しで引数がない場合は基本的に()をつけず、returnも省略可能

Rubyのメソッド呼び出しは、引数がない場合、括弧(())を付けなくても問題ないです。基本的には付けてないコードが多いと思います。

また、メソッドから値を返す際に、return キーワードを明示的に書かなくても、最後に評価された式の結果が自動的に返されます。

Pythonの例:

def greet():
    return "Hello, world!"

print(greet())  # "Hello, world!"

Rubyの例:

def greet
  "Hello, world!"  
end

puts greet # "Hello, world!"

同じ機能を持つメソッドが複数存在する

Rubyでは、同じ機能を持つメソッド(エイリアスメソッド)が多く存在するように感じます。

同じ動作をするコードのバリエーションも多いので、Rubyを使用する場合は、チーム内でコーディングスタイルを明確にすることが重要だと感じています。

静的コード解析ツールのRubocopを使用することでコーディングスタイルに一貫性を保つことができ、この問題はある程度解決可能だと思っています。

Pythonの例:

# Pythonでは、len を使用して文字列の長さを取得する
str = "Hello, World!"
len(str)  # 13

Rubyの例:

# Rubyでは、length と size で文字列の長さを取得できる
str = "Hello, World!"
str.length  # 13
str.size  # 13

MVC と MTV

DjangoはMTV(Model-Template-View)アーキテクチャを、RailsはMVC(Model-View-Controller)アーキテクチャを採用しています。

Modelに関しては基本的に同じ役割を果たしますが、DjangoのViewはRailsのControllerに対応し、DjangoのTemplateはRailsのViewに対応します。

それぞれの違いについて、具体的な感想を以下に記載します。

Model

モデルの役割は基本的に同じですが、データベースのテーブルやカラムの情報をモデル内に定義するかどうかが違いました。

Djangoのモデルでは、データベースのテーブルとそのカラム(フィールド)は、モデルクラス内に直接定義されます。この方法は、モデルクラス自体がそのテーブルの完全なスキーマを表現していると考えることができます。

Djangoのモデルの例:

from django.db import models

class User(models.Model):
    name = models.CharField(max_length=200)
    email = models.EmailField()
    joined_at = models.DateTimeField(auto_now_add=True)

一方、Railsではモデルクラス自体はテーブルのスキーマを持たず、その代わりにマイグレーションファイルとスキーマファイルにテーブルの定義が記述されます。Railsのモデルは主にビジネスロジックとバリデーションルールを定義する場所です。

Railsのモデルの例:

class User < ApplicationRecord
    validates :name, presence: true
    validates :email, presence: true, uniqueness: true
end

対応するマイグレーションファイルには以下のような記述があります。

class CreateUsers < ActiveRecord::Migration[5.2]
  def change
    create_table :users do |t|
      t.string :name
      t.string :email
      t.timestamps
    end
  end
end

Djangoではモデルだけを見ればデータベースの構造がわかるという利点がありました。一方、Railsではモデルがシンプルに保たれるため、ビジネスロジックに集中できるというメリットがあると感じています。

View

DjangoのテンプレートとRailsのビューで使われるERBというテンプレートエンジンは基本的に似たような構造でした。

Djangoテンプレートの例:

{% for user in users %}
    <p>{{ user.name }}</p>
    <p>{{ user.email }}</p>
{% endfor %}

ERBの例:

<% @users.each do |user| %>
    <p><%= user.name %></p>
    <p><%= user.email %></p>
<% end %>

私たちのチームではSlimというテンプレートエンジンを使用しているため、Djangoの時とは大きく異なりました。最初は独特な書き方に慣れませんでしたが、慣れてしまうとSlimの方が簡潔で見やすいコードになると感じています。

Slimの例:

- @users.each do |user|
  p = user.name
  p = user.email

Controller

コントローラーはDjangoのビューに対応しますが、大きな違いとしてはDjangoのビューは自由度が高いことに対して、Railsのコントローラーは構造やメソッド名が原則決められていることだと思います。

Djangoのビューはアプリケーションによって、関数またはクラスベースにするかを決め、名前も自由に決めることができます。

ビューの例:

# 関数ベースのビュー
def post_list(request):
    posts = Post.objects.all()
    return render(request, 'blog/post_list.html', {'posts': posts})

# クラスベースのビュー
from django.views import View

class PostListView(View):
    def get(self, request):
        posts = Post.objects.all()
        return render(request, 'blog/post_list.html', {'posts': posts})

Railsのコントローラーでは、一般的に7つのメソッド名( index, show, new, create, edit, update, destroy)が使用されます。

この7つを使ってCRUD(Create, Read, Update, Delete)操作をカバーできるため、基本的には同じような構造になると思います。

コントローラーの例:

class PostsController < ApplicationController
  # すべての投稿を表示する
  def index
    @posts = Post.all
  end

  # 特定の投稿を表示する
  def show
    @post = Post.find(params[:id])
  end

  # 新しい投稿を作成するためのフォームを表示する
  def new
    @post = Post.new
  end
end

個人的には、アプリケーションの構造や命名について考える必要がないRailsのコントローラーの方が早く書けるので好きです。

まとめ

まだRailsの使用歴が短いため、完全に理解しているわけではないですが、Djangoに慣れていると気をつける点が結構あると感じました。

特に、別のファイルに書かれているメソッドがインポートなしで利用可能であったり、Rails独自のメソッドが多数存在したりで、初期の頃はよく混乱しました。

その一方で、Djangoより設定の記述やインポートが少ない点は、Railsの大きな利点であると感じていて、Railsの原則に慣れることで開発速度は大幅に向上すると思っています。

これからもっとRailsについて理解を深め、開発効率を上げていきたいです。

Linc'well, inc.

Discussion