質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

Ruby on Rails 4

Ruby on Rails4はRubyによって書かれたオープンソースのウェブフレームワークです。 Ruby on Railsは「設定より規約」の原則に従っており、効率的に作業を行うために再開発を行う必要をなくしてくれます。

Q&A

解決済

1回答

2362閲覧

Railsにおいての用語というか、よく見かける単語などについての質問です

teruwa

総合スコア49

Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

Ruby on Rails 4

Ruby on Rails4はRubyによって書かれたオープンソースのウェブフレームワークです。 Ruby on Railsは「設定より規約」の原則に従っており、効率的に作業を行うために再開発を行う必要をなくしてくれます。

0グッド

2クリップ

投稿2016/09/06 15:06

『モデルオブジェクト」ってなんのことですか?
@news_send = NewsSend.new(message_params)
例えばこういう記述がされたコントローラーがあった場合、
この「@news_send」の部分がモデルオブジェクトだと聞きました
ですが命名規則?のようなものから考えると、「NewsSend」も最初の文字が大文字で単数系なのですからモデルの名前ですよね?
これらモデルオブジェクト名とモデル名は違うものなのですか?

あと
ビュー上に

<%= form_for(@news_send,url: news_index_path) do |f| %>
題名:<br />
<%= f.text_field :news_title %><br />

とあったのですが「@news_send」の部分はフォームに入力された情報を送る先という認識はあっていますか?
となるとこれはユーザーが勝手に定義して「@news_send」と命名した変数(送り先)ということですか?
「:news_title」というのはカラムを指定しているというのはなんとなくわかるのですが、そのカラムがあるテーブルはどこで指定しているのでしょうか?

最後に、
コントローラー上に
def index
@news_send = NewsSend.new
end

def create @news_send = NewsSend.new(message_params) @news_send.save redirect_to root_path , notice: '投稿完了です' end

とあったのですが、
最初のdef indexの部分でNewsSendモデルのオブジェクトの初期化を行っていると聞いたのですが、
なぜ初期化しないとまずいのでしょうか?
def createのほうにも@news_send = NewsSend.newと似た記述があると思うのですがこれとは違うのですか?(こっちはmessage_paramsとついてはいますが、、、)

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

❀良い質問ですね❀

この疑問はRailsから入門した方が直面する、通過儀礼のようなものだと思ってください。
ただし、あなたにはコードに対して疑問を持つ、プログラマーとしての才能があるようです。

Railsとは、Ruby on Railsの略ですが、つまりRubyを前提としています。
クラス・インスタンス・インスタンス変数・ローカル変数
この辺の理解をすることでRailsをより深く、本質的に、また将来迷うことなく学んでいけるようになるでしょう。

もしくは、形式的なルールに従っても、Railsはある程度書くことができ、またそこそこに都合よく動きます。
しかし、あなたがもしこれからRubyを使って数年単位で何かをやろうとしているのであれば、
間違いなくRubyの正しい習得から始めることをおすすめします。


名称意味・働き
モデル/クラスRailsが採用している、ActiveRecord::Baseのクラスの一種。データベースにある同じ名前のテーブル構造と対応する。
モデルオブジェクト/インスタンス正式名称ではないですが、恐らくモデルのインスタンスのこと
@news_sendいま書いてるコントローラと、ビューで利用できる、任意のインスタンス変数のこと。実は名前はなんでもよい
NewsSend.new(message_params)NewsSendというモデルから、newメソッドを通してモデルオブジェクト(インスタンス)を生成している
ビューの中の@news_sendコントローラでたくさん変数を使いますが、そのうちビューで利用するものを特別にインスタンス変数に代入している。これも名前は自分できめてよい
インスタンス変数クラスから生成したインスタンスの中で利用できる変数で、メソッドをまたいで利用できる。
ローカル変数アクション中でしか利用できない変数のことです。ビューにも渡せませんが、ビューで必要ないデータはローカル変数で書くと、利用範囲が明確になって便利です。
コントローラ実はあなたはアクション(index, createなど)に入った時点で、ナントカControllerが予めnewを通してインスタンス化されたものを見ています。

ややこしいのですが、モデルというのはRails用語になります。
Rubyで言う所のクラスが、Railsによって機能が付け加えられ、モデルという名前を付けられています。

同様にモデルオブジェクトは、この特別にモデルと名前のついたクラスの、インスタンスのことを指します。
なので、クラスとインスタンスという言葉をベースに考えていただければ、世の中の情報的にも理解しやすいです。

これらを踏まえて、回答

1つめ

この「@news_send」の部分がモデルオブジェクトだと聞きました
ですが命名規則?のようなものから考えると、「NewsSend」も最初の文字が大文字で単数系なのですからモデルの名前ですよね?
これらモデルオブジェクト名とモデル名は違うものなのですか?

上の表の通り、@news_sendに代入されたオブジェクトは、NewsSendモデル(クラス)のインスタンスとなります。
@news_send = NewsSend.new(略) とセットで書かれているようですが、この左側と右側に特に脈絡はありません。

NewsSend.newが返す値の代入先は、@hoge でも、@huga でも構いません。
これは主にビューに渡すとき、またビューから見た時にあなたが扱いやすい、好きな名前を決めてあげてください。

一般的には、名前が自由すぎるとあとで忘れて使いづらいので、モデルの名前をスネークケースで単数形を表現します。
NewsSend(キャメルケース)をスネークケースで表現すると、news_sendとなります。

さらに、インスタンス変数は @ほにゃらら と書くため、
これをインスタンスう変数で扱いたい場合は @news_send という形で書きます。

このインスタンス変数に代入することによって、ビューから呼び出せるようになります。
(試しに@を外してビューから利用する形で実行してみてください。)


2つめ

ビュー上に

<%= form_for(@news_send,url: news_index_path) do |f| %> 題名:<br /> <%= f.text_field :news_title %><br /> <% end %>

とあったのですが「@news_send」の部分はフォームに入力された情報を送る先という認識はあっていますか?

鋭いですね。
概ね、合っています。
が、@news_sendはNewsSendのインスタンスでしかありません。

これは追々、Railsの学習を進めていくことで理解が深まると思いますが、
form_forは@news_sendに入っているNewsSendのインスタンスの、
DBへの保存状態によってリクエストする先が変わるというカラクリをもっています。

@news_sendがまだNewsSend.newしたててで、saveをしていない時、こちらはcreateアクションに飛ばすように便宜を図ります。
一方、@news_sendがsave済みの場合、updateアクションに飛ばすようになります。

また、オプションにてリクエスト先は自由に変更できますが、
一般的にはこのRailsの仕組みをうまく使って書く内容を減らしながら作っていきます。

なお、NewsSendからwhereや、find_by(find)をした時は、save済みなのでupdateに飛びます。

蛇足ですが、@hoge = NewsSend.newとした場合、当然form_for(@hoge, ..略..)となります。


3つめ

最初のdef indexの部分でNewsSendモデルのオブジェクトの初期化を行っていると聞いたのですが、
なぜ初期化しないとまずいのでしょうか?

初期化に関してはもうお分かりかもしれませんが、@news_sendは任意のインスタンス変数ですので、
ただ@news_sendと書いた所で、中身は自動的にnilになります。

その上で、新しいレコード( モデルオブジェクト/モデル(クラス) のインスタンス)を作成するので、
newを使った初期化が必要になります。

話が少し前後しますが、NewsSendというモデルはテーブル全体を表しています。
一方で、NewsSendのインスタンスは、テーブル内の各レコードを表しています。

User

idname保存
1hogeされてる
2hugaされてる

このようなテーブルがあったとき、Userは表そのものを表しますが、
User.find_by(id: 1)は id: 1, name: 'hoge'のレコードを指します。

ここに、新しいレコードを追加しようとしたとき、

User

idname保存
1hogeされてる
2hugaされてる
nilpiyoされてない

最後尾のname: 'piyo'のものをUser.newを通して作成します。

具体的には以下のように。

ruby

1user = User.new(name: 'piyo') 2user.save

このuser.save が呼び出されタイミングで、

User

idname保存
1hogeされてる
2hugaされてる
3piyoされてる

自動的にidが振られ、晴れてデータベースに保存されるようになります。

なお、

def createのほうにも@news_send = NewsSend.newと似た記述があると思うのですがこれとは違うのですか?(こっちはmessage_paramsとついてはいますが、、、)

一つのリクエストに対して一つのコントローラのインスタンスが新たに生成されますので、
indexを受け付けた時と、createを受け付けた時とで異なるインスタンスの中にいます。

そのため、同様に見えますがindexでnewしたものはレスポンスを返すと同時にメモリから開放されてしまい、
その後を追いかけることはできません。
WEBサーバーですから、indexのリクエストの後に、createに来るユーザーが同一人物だとは限らないわけです。

そのため、indexでは空のレコードを使い、フォームのHTMLを生成するために利用し、
createでは実際に飛んできた値をNewsSendのカラムとして扱うことで保存できるようにしています。

複数の側面があるため、一概に同じ見た目でも全く同じ機能性というわけではないので、各所で注意が必要です。

(Rubyのクラスでそのままブラウザとやり取りできたらみんなハッピーなんですけど、
残念ながらサーバーとブラウザがやり取りしているのはただの平ったい文字列なんです...。)


非常に長くなってしまって恐縮ですが、
Railsのテキストなどはこの辺をすっ飛ばして解説することが多いために躓く人を多く見てきました。
この長文が何かのお役に立てば幸いです。

投稿2016/09/06 17:53

TatumakiGen

総合スコア72

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問