はじめに
Ruby on Railsの学習内容をまとめています。
メソッドとは
複数の処理を1つにまとめて扱いやすくしたもののことをメソッドと言います。
メソッドは、自分で定義することも可能です。
例)
.length => 文字列の数を計算 例) puts “プログラミング”.length
.reverse => 文字列を逆に表示する 例) puts “programing”.reverse
.include? => 引数に指定した文字列が含まれているかどうかを調べる
例)puts “ruby on rails”.include?(“rails)
.methods => 使用可能なメソッドを一覧で表示できるmethodsメソッド
例) puts “Ruby on Railsでアプリ開発”.methods
メソッドを定義する
メソッドを定義するには、実行する処理内容をdef ~ end 内に記述します。
def メソッド名(引数) # 引数は任意
# 実行する処理内容
end
メソッドを呼び出すには、そのメソッド名を記述します。
def greeting
'Hello'
end
puts greeting
注意
プログラムは、上から下に順番に処理されます。
このため、自分で定義したメソッドを使うには、定義の後に呼び出す必要があります。
また、メソッドは呼び出されない限り、処理が実行されないという点も覚えておきましょう。
引数とは
「引数」は、メソッドを呼び出す際、メソッドに渡す値のことです。
通常、メソッド名(引数) の形で記述しますが、先ほどのgreeting.rbのように引数は省略も可能です。
引数の値は、メソッドを定義した側で好きな変数名をつけられます。
def greeting(name)
"Hello, #{name}!" # この行のnameは、引数で渡すname
end
puts greeting('John') # 'John'を引数として渡す
補足として、ここでgreeting.rb内で使った、ダブルクォーテーション("Hello, #{name}!")とシングルクォーテーション('John')の違いを説明しておきます。
どちらも文字列を囲む際に使用できますが、ダブルクォーテーションは文字列の中で式展開を行いたい場合や、改行文字(\n)等のエスケープシーケンスを使用したい場合に有用です。
反対に、これらのことはシングルクォーテーションでは行えません。
文字列を使う際はどちらを使うべきかを考えながら宣言するとよいでしょう。
戻り値とは
「戻り値(返り値)」は、メソッドが呼ばれたときに返ってくる値のことです。
def ~ end 処理内の最終結果が戻り値になります。
greeting.rbで定義したgreetingメソッドでは、
「"Hello, #{name}!"」が戻り値になります。
def greeting(name)
"Hello, #{name}!"
"Good morning, #{name}!"
end
puts greeting('John')
returnによる戻り値
戻り値は、returnを使って明示的に指定することもできます。
returnを省略した場合は、先ほどのように「最終結果」が戻り値になります。
def greeting(name)
return "Hello, #{name}!"
"Good morning, #{name}!"
end
puts greeting('John')
Fizz_Buzz
def fizz_buzz(number)
if number % 15 == 0
"fizz_buzz"
elsif number % 5 == 0
"fizz"
elsif number % 3 == 0
"buzz"
else
number.to_s
end
end
puts "数字を入力してください"
input = gets.to_i
puts "結果は"
puts fizz_buzz(input)
クラス、メソッド、インスタンスの関係(重要)
クラスは、オブジェクト指向プログラミングの基本的な構成要素であり、オブジェクトの設計図のようなものです。クラスには、オブジェクトが持つべき属性(プロパティ)や操作(メソッド)が定義されています。例えば、あるショッピングアプリで商品を表現する場合、「Product」というクラスを作成し、その中に商品名や価格、在庫数などの属性を定義し、商品の登録や削除といった操作を行うメソッドを定義することができます
インスタンスは、クラスから生成されるオブジェクトのことで、クラスの設計図に基づいて具体的なデータを持つオブジェクトが生成されます。例えば、先ほどの「Product」クラスから、実際の商品「りんご」や「バナナ」などのインスタンスを作成することができます。これらのインスタンスは、それぞれが独自の属性(商品名や価格など)を持ち、クラスで定義されたメソッドを利用することができます。
メソッドは、クラス内で定義された操作のことで、特定のタスクを実行するためのコードがまとめられています。メソッドは、インスタンスに対して呼び出すことができ、そのインスタンスの属性にアクセスしたり、他のメソッドと連携して処理を行ったりします。例えば、「Product」クラスには、商品の在庫数を減らす「reduce_stock」メソッドが定義されているとします。このメソッドは、商品が売れたときにインスタンス(実際の商品)に対して呼び出され、そのインスタンスの在庫数を減らす処理を行います。
# Productクラスを定義
class Product
attr_accessor :name, :price, :stock
# 初期化メソッド
def initialize(name, price, stock)
@name = name
@price = price
@stock = stock
end
# 在庫数を減らすメソッド
def reduce_stock(amount)
if @stock >= amount
@stock -= amount
puts "#{@name}の在庫が#{amount}減りました。残り在庫数: #{@stock}"
else
puts "#{@name}の在庫が足りません。"
end
end
end
# インスタンスを生成
apple = Product.new('りんご', 200, 10)
banana = Product.new('バナナ', 100, 20)
# メソッドを呼び出す
apple.reduce_stock(3)
banana.reduce_stock(5)
インスタンスを作成・呼び出し
インスタンス名 = クラス名.new #作成
インスタンス名.メソッド名(引数) #呼び出し
レシーバのselfとは
まず、「self」はRubyの言語の中で特殊なキーワードで、現在のオブジェクトを参照するために使われます。オブジェクト指向プログラミングにおいて、オブジェクトはデータやメソッド(機能)を持っています。Rubyもオブジェクト指向言語なので、この概念が当てはまります。
では、「レシーバ」とは何でしょうか。「レシーバ」とは、メソッドが呼び出されるオブジェクトのことです。メソッドが実行される際、どのオブジェクトに対してそのメソッドが適用されるのかを指定するために、「レシーバ」が存在します。
例えば、Rubyで以下のようなコードがあったとします。
class Dog
def bark
puts "ワンワン"
end
end
dog1 = Dog.new
dog2 = Dog.new
dog1.bark
dog2.bark
この例では、Dogクラスのbarkメソッドが呼び出されています。dog1.barkと書かれている部分では、dog1オブジェクトが「レシーバ」であり、dog1オブジェクトに対してbarkメソッドが実行されます。同様に、dog2.barkではdog2オブジェクトが「レシーバ」となります。
では、「レシーバのself」とは何かというと、現在のオブジェクト自身が「レシーバ」である場合を指します。つまり、メソッド内でselfを使って、そのメソッドが呼び出されたオブジェクト自身に対してメソッドを適用したい場合に使われます。
例えば、以下のようなコードがあったとします。
class Dog
def initialize(name)
@name = name
end
def greet
puts "こんにちは、私は#{self.name}です!"
end
def name
@name
end
end
dog = Dog.new("ポチ")
dog.greet
この例では、greetメソッド内でself.nameと書かれています。これは、「現在のオブジェクト(ここではdogオブジェクト)に対してnameメソッドを適用して、その結果を使いたい」という意味になります。
この場合、selfはdogオブジェクトを指していますので、self.nameはdog.nameと同じ意味になります。
この例では、selfを使って、greetメソッドが呼び出されたオブジェクト自身(dogオブジェクト)のnameメソッドを呼び出しています。こうすることで、オブジェクトが持つデータ(ここでは@nameインスタンス変数)を適切に取り扱うことができます。
このように、「レシーバのself」とは、現在のオブジェクト自身が「レシーバ」として、そのオブジェクトに対してメソッドを適用することを意味します。これを理解することで、オブジェクト指向プログラミングの基本概念をより深く掴むことができます。
継承とは
既にクラスで定義したメソッドを別のクラスでも受け継ぐことを継承と言います。
継承では、元となるクラスを親クラス(スーパークラス)
メソッドを受け継ぎ、新しく作成するクラスを子クラス(サブクラス)と呼びます。
クラス間のこのような関係を「継承関係」と言います。
継承をすると、子クラスから親クラスのメソッドを呼ぶことが出来るようになります。
継承を活用することで、以下のようなメリットが得られます。
- コードの再利用性が向上する: 共通の機能やデータを親クラスにまとめることで、それを継承する子クラスで再利用することができます。これにより、コードの重複を避けることができます。
- プログラムの設計が容易になる: オブジェクト指向プログラミングでは、プログラムの設計が重要です。継承を使うことで、クラスの階層構造を明確にし、各クラスの役割や関係性を整理しやすくなります。
- 保守性が向上する: 継承を活用すれば、親クラスで共通の機能を修正するだけで、それを継承するすべての子クラスに変更が適用されます。これにより、プログラムの保守が容易になります。
オーバーライドとは
オーバーライドとは、オブジェクト指向プログラミングにおいて、子クラスが親クラスで定義されているメソッドを上書きして、独自の振る舞いを定義することを指します。オーバーライドを利用することで、親クラスのメソッドをそのまま利用するのではなく、子クラスに応じた適切な振る舞いを実現できます。
オーバーライドのメリット
似ている機能を1つのメソッド名に合わせて、それぞれの子クラスで適した処理を定義する事ができる
superとは
子クラスのメソッド内で定義すると、親クラス内にある同じ名前のメソッドを呼び出すことができる
superの書き方は、メソッド内に「super」と定義するのみ。
シンボルとは
シンボルは、Ruby言語において一意な識別子を表現するためのデータ型です。シンボルは、コロン(:)に続く名前で表現されます。例えば、:apple や :user_name などです。シンボルは、名前が同じであれば必ず同じオブジェクトを参照します。そのため、シンボルはメモリ効率が良く、処理速度も高速です。
<シンボルと文字列の違いとは>
シンボルは文字列の前にコロン(:)で定義する
文字列はダブルクォーテーション("")で囲んで定義する
シンボルは書き換えられない
文字列は変更可能
シンボルは同じオブジェクトを参照している(一意性がある)
文字列は同じオブジェクトではない
シンボルは文字列よりも処理が高速
<どういう時に使うべきか>
処理が高速であるため、検索を行う時
ハッシュのキーなど「同じものが複数あると困るもの」を扱う時
HTTPメソッド
「HTTPメソッド」は、HTTPリクエストをする際に、通信のやり取りの要求を定義したものです。
代表的なHTTPメソッドは、「GET」「POST」「DELETE」の3種類です。
GET:リソースの取得
ブラウザからサーバーへURLを送信し、ウェブページを取得(GET)します。
単にウェブサイトを閲覧する際は、GETメソッドが使われます。
POST:リソースの更新、リソースへのデータ追加 など
ブラウザからサーバーへ、URL以外のデータも送信(POST)して処理を命令します。
会員情報の登録、記事投稿など、サーバーに情報を送信する際に使用します。
DELETE:リソースの削除
ブラウザからサーバーへ、URL以外のデータ削除のための情報も送信して処理を命令します。
会員情報の削除、記事削除など、情報を削除する際に使用します。
モデルについて
「モデル」は、Ruby on Railsにおいて、データの構造やビジネスロジックを扱うためのコンポーネントです。モデルは、アプリケーション内のデータを表現するためのクラスであり、データベースとのやり取りやデータのバリデーションなどを担当します。モデルは、MVC(Model-View-Controller)アーキテクチャの「Model」に相当します。
- データの表現: モデルは、アプリケーション内で扱われるデータを表現するためのクラスです。例えば、ユーザーや商品などのデータを表現するためにそれぞれのモデルが作成されます。
- データベースとのやり取り: モデルは、データベースとアプリケーション間でデータのやり取りを行います。データの追加、更新、削除、検索などの操作がモデルを通じて実行されます。
- データのバリデーション: モデルは、データの整合性を保つためにバリデーションを行います。例えば、メールアドレスの形式が正しいかどうかや、パスワードの長さが適切かどうかなどのチェックを行います。
- ビジネスロジックの実装: モデルは、アプリケーション固有のビジネスロジックを実装する場所でもあります。例えば、ユーザの年齢を計算するメソッドや、商品の価格を計算するメソッドなどがモデル内に実装されます。
コントローラとは
コントローラ(Controller)は、Ruby on Rails(Rails)アプリケーションにおいて、ユーザーからのリクエストを受け取り、適切な処理を行い、最終的にユーザーに表示するビューにデータを渡す役割を担っています。コントローラはアプリケーションのロジックの中心であり、MVC(Model-View-Controller)デザインパターンにおいて、モデルとビューをつなぐ重要な役割を果たしています。
コントローラが存在する理由は、アプリケーションの機能を整理し、ユーザーからのリクエストに対して適切なレスポンスを生成するためです。コントローラはアプリケーションの各機能を表すアクション(メソッド)を持ち、ルーティングによって特定のURLリクエストが対応するアクションに割り当てられます。
コントローラ内で行われる典型的な処理は以下の通りです:
- パラメータの取得:ユーザーからのリクエストに含まれるパラメータ(フォームの入力値など)を取得します。
- データの取得・操作:モデルを通じてデータベースからデータを取得したり、データを操作(作成、更新、削除)したりします。
- データの整形・加工:必要に応じて取得したデータを加工したり、整形したりします。
- インスタンス変数にデータを格納:ビューに渡すために、データをインスタンス変数に格納します。インスタンス変数は、コントローラからビューにデータを受け渡すために使用されます。
- ビューの選択:どのビューを表示するかを指定します。通常、アクション名に対応するビューが自動的に選択されますが、必要に応じて別のビューを指定することもできます。
- レスポンスの生成:最終的にビューにデータを渡し、レンダリングされたHTMLがユーザーに返されます。
コントローラは、アプリケーションの機能を整理し、アプリケーションのロジックを中心的に扱う役割を果たしています。これにより、アプリケーションのコードが整理され、保守や拡張が容易になります。また、コントローラはモデルとビューの間の橋渡し役を担うことで、データの取得や操作と表示を分離し、アプリケーション全体の設計が明確になります。
Railsでは、「一つのコントローラは一つのリソース(データの種類や機能のまとまり)に対応する」という原則が推奨されています。これにより、コントローラが担当する範囲が明確になり、アプリケーション全体の設計が整理されます。
例えば、ブログアプリケーションでは、「記事」に関する機能を持つPostsControllerと、「コメント」に関する機能を持つCommentsControllerを作成することが一般的です。それぞれのコントローラ内には、リソースに対するCRUD操作を表すアクションが定義され、ルーティング設定によってURLリクエストが対応するアクションに割り当てられます。
コントローラに定義する7つのアクション名
モデルを扱うコントローラでは、データを操作するための7つのアクションを以下の名前で定義するのが一般的です。 もちろん、これら以外に必要なアクションがあれば必要に応じて用意しますが、これらの機能を実装するときにはこのアクション名で実装するようにしましょう。次のレッスンで紹介しますが、これらの名前を使わないと便利な省略記法を利用することができません。
また、コントローラに記述するときもこの順番に記述するのがrailsのレールに則った方法です。
アクション名 | 役割 |
---|---|
new | データの新規作成フォームを表示する |
create | データを追加(保存)する |
index | データの一覧を表示する |
show | データの内容(詳細)を表示する |
edit | データを更新するためのフォームを表示する |
update | データを更新する |
destroy | データを削除する |
HTTPリクエストについて
HTTP | 用途 |
---|---|
GET | データの取得(ページ自体もデータ) |
POST | 新しいデータの作成 |
PUT | 既存のデータの更新 |
PATCH | 既存のデータの一部更新 |
DELETE | 既存のデータを削除 |
form_withヘルパーとは
Railsには、Viewなどから呼び出す共通処理をまとめた「ヘルパーメソッド」が用意されています。
form_withヘルパー(以下、form_with)もその1つで
セキュリティ対策などが組み込まれた安全なHTMLのformタグを作成でき、またRailsの機能を最大限生かすことが可能です。
form_withヘルパーを使う際には、主に以下のようなシチュエーションで使用されます。
- 新規データの作成:フォームで入力されたデータをデータベースに保存する際に使用されます。
- 既存データの編集:フォームで入力されたデータを使って、データベースの既存データを更新する際に使用されます。
<%= form_with model: @example, local: true do |f| %>
正確には
<%= form_with model: @example, url: ‘/url’, method: :HTTPリクエスト(post, deleteなど) local: true do |f| %>
フォームの内容
<% end %>
ここで、@exampleは、コントローラから渡されたインスタンス変数で、モデルのインスタンスを指します。また、local: trueは、非同期通信ではなく、通常の同期通信でフォームを送信するためのオプションです。
フォーム内には、<%= f.label %>や<%= f.text_field %> <%= f.submit %>など、さまざまなヘルパーメソッドを使ってフォームの要素を定義できます。
例えばブログアプリなどで”title”,”body”に情報を入力させそれをモデルにあるtitle,bodyに格納させたい場合は
<%= form_with model: @モデル名 do |f| %>
form_withはこのようにモデルと連携することで、データを簡単に保存ができたり
バリデーションなどを簡単に設定することができます。
またデータベースに保存する際に、@モデル名といった新しい情報がmodelオプションに設定されている場合は
CreateアクションのURLへ送信といった風に、データの送信先を自動的に判別することができます。
つまり今回の場合は、modelオプションで@モデル名を設定するだけで、自動的CreateアクションのURLへ送信することができるということになります。
[@モデル名]はコントローラで事前に記述したインスタンス変数。
インスタンス変数とは(重要)
インスタンス変数とは、オブジェクト指向プログラミングにおいて、クラスの各インスタンス(オブジェクト)に属する変数です。インスタンス変数は、オブジェクトごとに独立した値を持ち、そのオブジェクトの状態を表します。
例えば、人間を表す「Person」というクラスがあるとしましょう。このクラスには、名前(name)と年齢(age)という属性があります。これらの属性をインスタンス変数として定義することで、Personクラスの各インスタンス(つまり、個々の人間)が独自の名前と年齢を持つことができます。
Rubyでは、インスタンス変数は先頭に@を付けることで識別されます。以下に、Personクラスの例を示します。
class Person
def initialize(name, age)
@name = name
@age = age
end
def show_info
puts "名前: #{@name}, 年齢: #{@age}"
end
end
person1 = Person.new("山田", 30)
person2 = Person.new("鈴木", 25)
person1.show_info # => "名前: 山田, 年齢: 30"
person2.show_info # => "名前: 鈴木, 年齢: 25"
この例では、@nameと@ageがインスタンス変数です。それぞれのインスタンス(person1とperson2)が独立した名前と年齢を持つことができます。
インスタンス変数を使う理由としては、以下のような点が挙げられます。
- オブジェクトの状態を保持する: オブジェクトはそれぞれ独立した状態を持ち、その状態を操作・参照できるようになります。
- オブジェクト間のデータのやり取りを容易にする: クラス内のメソッドや他のクラスのメソッドから、インスタンス変数にアクセスしてデータを操作・参照できます。
特に、Ruby on Rails(以下、Rails)では、コントローラで定義されたインスタンス変数は、対応するビューに渡されるため、データベースから取得したデータを表示したり、フォームにデータを渡したりする際に、インスタンス変数が使われます。例えば、先ほどのform_withヘルパーの例では、@exampleというインスタンス変数が使われていました。これは、コントローラでデータを取得または新規作成し、ビューにデータを渡すために使用されています。以下に、Railsでのインスタンス変数の使い方の例を示します。
# app/controllers/examples_controller.rb
class ExamplesController < ApplicationController
def new
@example = Example.new
end
def create
@example = Example.new(example_params)
if @example.save
redirect_to @example
else
render 'new'
end
end
private
def example_params
params.require(:example).permit(:name, :age)
end
end
上記のコードでは、newアクションでExample.newで新しいオブジェクトを作成し、@exampleインスタンス変数に代入しています。このインスタンス変数は、new.html.erbというビューに渡され、form_withヘルパーでフォームを作成する際に使用されます。
createアクションでは、フォームから送信されたデータ(example_params)を使って、新しいExampleオブジェクトを作成し、@exampleインスタンス変数に代入しています。その後、データの保存に成功すれば詳細ページにリダイレクトし、失敗すれば再度新規作成ページを表示します。
このように、インスタンス変数を使うことで、コントローラとビュー間でデータを簡単にやり取りでき、データベースのデータを表示・操作する際に効率的に開発を進めることができます。
Q.ストロングパラメータをprivateより下に書く理由
A.ストロングパラメータをURLに紐付けて呼び出す必要がないため