Ruby on railsとDjangoの違いまとめ~基礎編~

##1. はじめに
　プログラミングを始めて4ヶ月の初心者です！
Ruby on railsとDjangoを勉強中なので、
アウトプット(備忘録)として、その基礎的なコードの違いを書いていきたいと思います！！:pencil2::beginner:
railsから学習を始めていることから、
基本rails目線で、Djangoの場合はどうか？という目線で書いております:smile:
少しでも、ご参考になりましたら幸いです。
（勉強中なので、随時追記・修正していく予定です！）

##2. <font color="red">MVCモデル(Rails)</font>と<font color="blue">MTVモデル(Django)</font>
"View"の名前が被っているので、ややこしい感じがしますが、大まかな流れは同じです。
自分のイメージを以下に示します。
<img width="1020" alt="スクリーンショット 2020-01-04 20.46.48.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/542326/2fa860bc-48bd-8dbe-4f61-23dad0eff9b1.png">

##3. ルーティング編

(Railsの場合）
routes.rbに記載していきます。
ターミナル上で"rake routes"を叩けば、URLパターンやprefixを確認できます！

```Ruby:config/routes.rb
root 'products#index'
get 'index', to: 'products#index'
```

(Djangoの場合）
urls.pyに記載していきます。
path()関数を使用し、これは引数にroute,view,name,kwargsの4つの引数を取ります。
ここでは、ルートURL('')に、viewのindex関数を対応させ、indexという名称で他のファイル(templateなど）から呼び出せるようにしています。
viewにおいて汎用クラスを呼び出す場合は、"as_view"を使用します。

```Python:app/urls.py
from django.urls import path
from . import views

app_name = "アプリ名"

urlpatterns = [
    path("", views.index, name="index"),
    path("products/", views.ProductListView.as_view(), name="products_list"),
]
```

## 4. コントローラー/ビュー編
####4-1. htmlファイルの指定方法

(Railsの場合）
controllerのアクション名と同じ名前のviewが呼び出されるというルールがありますので、
特にコードは必要なく、アクション名と同名のviewファイルを準備することで、そのview(html)ファイルが呼び出されます。

```Ruby:controllers/products_controller.rb
def index
end
```
```Ruby:views/index.html.erb
.title
  haml等でhtmlを記載していきます
```

(Djangoの場合）
関数を使用するか、クラスを使用するかによって、
それぞれ、renderメソッドかtemplate_nameメソッドを使用します（他にもいっぱいあるようです）

```Python:app/views.py
# 関数を使用する場合
def index(request):
    return render(request, "index.html")

# クラスを使用する場合
class ModelListView(ListView):
  model = Model
  template_name = "index.html" 
```

####4-2.インスタンス変数のhtmlファイルへの渡し方

(Railsの場合）
htmlファイルにおいて、変数を使用するために、@をつけて、インスタンス変数を定義します。

```Ruby:products_controller.rb

def index
  @product = Product.where(id: 1..10)
end

```

(Djangoの場合）
変数がないのにhtmlファイルでデータが扱える、というのが衝撃的です！

```Python:views.rb
class XxxListView(LoginRequiredMixin, ListView):
  model = Xxx
  template_name = "xxx.html"
  # templateにおいて、xxx_listで配列としてデータが使用できる

  def get_context_data(self, **kwargs):
    context["hennsu"] = "value"
    return context
    #本メソッドで"hennsuという変数を渡すことができます
```
（とはいっても、get_context_dataやget_querysetで変数の定義やデータの選択が可能です）


## 5. ビュー/テンプレート編

####・部分テンプレートの書き方

（Railsの場合）
renderメソッドを使用します。

```Ruby:index.html.erb
<%= render '(フォルダ名/)yyy.html.erb' %>
-# render先は'_yyy.html.erb'という名称とします
```

（Djangoの場合）

```Python:base.html
{% block content %}
  # ここに他のhtmlファイルを差し込みます
{% endblock %}
```

```Python:index.html
{% extends "base.html" %}
{% block content %}
  # この部分をbase.htmlに差し込みます（逆かもしれません）
{% endblock %}
```

ここはrailsの方が自由度が高いかと思います。

####・ログインしているユーザー情報の表示

(Railsの場合）

```Ruby:view.html.haml
 - if user_signed_in?
   %div
     current_user.name
```

(Djangoの場合）

```Python:template.html
{% if user.is_authenticated %}
  <div> User Name: {{ user.username }} </div>
```

## 6. モデル編
####・マイグレーション
(Railsの場合）
モデルの作成 (rails g model Xxx) or マイグレーションファイルの作成 (rails g migration)
  ->マイグレーションファイルの記入
    ->マイグレーションの実行(rake db:migrate)

```Ruby:Migrationファイル
##一例です
  t.string :name,               null: false
```

(Djangoの場合）
models.pyへの記入
  ->マイグレーションファイルの作成(python manage.py makemigrations)
    ->マイグレーションの実行(python manage.py migrate)

```Python:models.py
class Xxx(models.Model):
  xxx = models.CharField(max_length=200)
  user = models.ForeignKey(User, on_delete=models.CASCADE)

  def __str__(self):
    return self.title
```


## 7. 感想

触っている時間が長いせいもあるかと思いますが、
railsの方がファイルの関係性も簡潔であり、
erbファイルにロジックが書けたりと、コードの自由度が高く、狙い通りのアプリを作成しやすい気がします。
一方で、Djangoは、やや構成に癖があるような気がします。
ただ、記述量が少なく、慣れたら速そうです。
さらに、pythonのメリットは豊富なライブラリにあると考えているので、
その豊富なライブラリをアプリで活かせるかどうか、が、ポイントのような気がしています。
（もっと勉強して、随時修正予定です！）
読んでいただきありがとうございました:bow_tone3: