2.3.1からやってみよう。
投稿(Micropost)の方も同じようにgenerateする。
> bundle exec rails generate scaffold Micropost content:text user_id:integer invoke active_record create db/migrate/20181121142643_create_microposts.rb create app/models/micropost.rb invoke test_unit create test/models/micropost_test.rb create test/fixtures/microposts.yml invoke resource_route route resources :microposts invoke scaffold_controller create app/controllers/microposts_controller.rb invoke erb create app/views/microposts create app/views/microposts/index.html.erb create app/views/microposts/edit.html.erb create app/views/microposts/show.html.erb create app/views/microposts/new.html.erb create app/views/microposts/_form.html.erb invoke test_unit create test/controllers/microposts_controller_test.rb invoke helper create app/helpers/microposts_helper.rb invoke test_unit invoke jbuilder create app/views/microposts/index.json.jbuilder create app/views/microposts/show.json.jbuilder create app/views/microposts/_micropost.json.jbuilder invoke test_unit create test/system/microposts_test.rb invoke assets invoke coffee create app/assets/javascripts/microposts.coffee invoke scss create app/assets/stylesheets/microposts.scss invoke scss identical app/assets/stylesheets/scaffolds.scss > bundle exec rails db:migrate == 20181121142643 CreateMicroposts: migrating ================================= -- create_table(:microposts) -> 0.0039s == 20181121142643 CreateMicroposts: migrated (0.0040s) ========================
db/migrateのタイムスタンプはUTCなんだね。
スキーマを確認しておこう。
sqlite> .schema microposts CREATE TABLE IF NOT EXISTS "microposts" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "content" text, "user_id" integer, "created_at" datetime NOT NULL, "updated_at" datetime NOT NULL);
textってデータ型使ったことないなあ・・・。
SQLite3でカラムに指定できるデータ型は「TEXT」「NUMERIC」「INTEGER」「REAL」「NONE」の5つです。
な、なるほど?ここで作られるテーブルスキーマはRDBMSによって違うのかな。TEXTがないDBもあるよね?つか、DB2にはないよね?
さて、演習。1は前と同じなのでパス。2はContentもUserも空にしたらどうなるか。空のレコードが作られるね。
sqlite> SELECT id, content, user_id FROM microposts WHERE user_id is NULL; 4||
今度はNULLが入ったっぽい。
演習3。長いのをいれるとどうなるか。SQLite3のTEXT型の制約とかあるのかな?
sqlite> SELECT id, content, user_id FROM microposts WHERE id = 3; 3|みっつめ。ながーいポスト。Ruby(ルビー)は、まつもとゆきひろ(通称 Matz)により開発されたオブジェクト指向スクリプト言語であり、スクリプト言語が用いられてきた領域でのオブジェクト指向プログラミングを実現する。 また日本で開発されたプログラミング言語としては初めて国際電気標準会議で国際規格に認証された事例となった。Ruby は1993年2月24日に生まれ、1995年12月にfj上で発表された。名称の Ruby は、プログラミング言語 Perl が6月の誕生石である Pearl(真珠)と同じ発音をすることから、まつもとの同僚の誕生石(7月)のルビーを取って名付けられた。競合言語として Perl の他に Python があり、「Matz(まつもと) が Python に満足していれば Ruby は生まれなかったであろう」と公式のリファレンスの用語集で言及されている[5]。機能として、クラス定義、ガベージコレクション、強力な正規表現処理、マルチスレッド、例外処理、イテレータ、クロージャ、Mixin、利用者定義演算子などがある。Perl を代替可能であることが初期の段階から重視されている。Perlと同様にグルー言語としての使い方が可能で、C言語プログラムやライブラリを呼び出す拡張モジュールを組み込むことができる。 Ruby 処理系は、主にインタプリタとして実装されている(詳しくは#実装を参照)。 可読性を重視した構文となっている。Ruby においては整数や文字列なども含めデータ型はすべてがオブジェクトであり、純粋なオブジェクト指向言語といえる。 長らく言語仕様が明文化されず、まつもとによる実装が言語仕様に準ずるものとして扱われて来たが、2010年6月現在、JRuby や Rubinius といった互換実装の作者を中心に機械実行可能な形で明文化する RubySpec という試みが行われている。公的規格としては2011年3月22日にJIS規格(JIS X 3017)が制定され、その後2012年4月1日に日本発のプログラム言語では初めてISO/IEC規格(ISO/IEC 30170)として承認された [4]。 フリーソフトウェアとしてバージョン1.9.2までは Rubyライセンス(Ruby License や Ruby'sと表記されることもある。GPLかArtisticに似た独自ライセンスを選択するデュアルライセンス)で配布されていたが、バージョン1.9.3以降は2-clause BSDLで配布されている。 |3
普通に入った。validationがないよねって確認か。4は削除。別に普通に削除できる。
さて、2.3.2だ。validationを入れてみようのコーナー。
class Micropost < ApplicationRecord validates :content, length: { maximum: 15} end
例は140字までになっているけど、それじゃ確かめるのが面倒なので、15文字にしてみる。
おお、ちゃんと機能してるね。画面はちょっとアレだけど。演習2でエラー画面を見てみようとなっている。 こんな感じ。
<div id="error_explanation"> <h2>1 error prohibited this micropost from being saved:</h2> <ul> <li>Content is too long (maximum is 15 characters)</li> </ul> </div> <div class="field"> <div class="field_with_errors"><label for="micropost_content">Content</label></div> <div class="field_with_errors"><textarea id="micropost_content" name="micropost[content]">15文字制限をつけてみたんだけど、どうかな?</textarea></div> </div>
ふむふむ。
では、2.3.3。テーブルの関連すな。
app/models/user.rb
class User < ApplicationRecord has_many :microposts end
app/models/micropost.rb
class Micropost < ApplicationRecord belongs_to :user validates :content, length: { maximum: 15} end
これで、ActiveRecordがちゃんと関連を認識してくれるかどうか。 rails consoleで確認してみる。rails consoleってirbなんだね。
> bundle exec rails console Loading development environment (Rails 5.1.6) irb(main):001:0> first_user = User.first User Load (0.7ms) SELECT "users".* FROM "users" ORDER BY "users"."id" ASC LIMIT ? [["LIMIT", 1]] => #<User id: 1, name: "太郎冠者", email: "taro@ex.com", created_at: "2018-11-21 11:49:49", updated_at: "2018-11-21 11:49:49"> irb(main):002:0> first_user.microposts Micropost Load (0.3ms) SELECT "microposts".* FROM "microposts" WHERE "microposts"."user_id" = ? LIMIT ? [["user_id", 1], ["LIMIT", 11]] => #<ActiveRecord::Associations::CollectionProxy [#<Micropost id: 1, content: "いっこめ。ほげほげ", user_id: 1, created_at: "2018-11-21 14:41:07", updated_at: "2018-11-21 14:41:07">]> irb(main):003:0> mp = first_user.microposts.first Micropost Load (0.4ms) SELECT "microposts".* FROM "microposts" WHERE "microposts"."user_id" = ? ORDER BY "microposts"."id" ASC LIMIT ? [["user_id", 1], ["LIMIT", 1]] => #<Micropost id: 1, content: "いっこめ。ほげほげ", user_id: 1, created_at: "2018-11-21 14:41:07", updated_at: "2018-11-21 14:41:07"> irb(main):004:0> mp.user Traceback (most recent call last): 1: from (irb):4 NoMethodError (undefined method `user' for #<Micropost:0x00007f959e832080>) Did you mean? user_id
あれ?最後動いてないぞ?あ、micropost.rbが保存されてなかった。
> bundle exec rails console Loading development environment (Rails 5.1.6) irb(main):001:0> mp = Micropost.first Micropost Load (0.1ms) SELECT "microposts".* FROM "microposts" ORDER BY "microposts"."id" ASC LIMIT ? [["LIMIT", 1]] => #<Micropost id: 1, content: "いっこめ。ほげほげ", user_id: 1, created_at: "2018-11-21 14:41:07", updated_at: "2018-11-21 14:41:07"> irb(main):002:0> mp.user User Load (0.3ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT ? [["id", 1], ["LIMIT", 1]] => #<User id: 1, name: "太郎冠者", email: "taro@ex.com", created_at: "2018-11-21 11:49:49", updated_at: "2018-11-21 11:49:49">
つまり、この関連の設定は別に繋がっている訳じゃなくて、それぞれmicropostsとuserというメソッドを 作る設定をしているってことね。
さて、演習1。/users/1にポストを表示してみる。viewを触るだけで十分。
app/views/show.html.erb
<p> <strong>Content:</strong> <%= @user.microposts.first.content %> </p>
これを追加するだけやね。表示してみる。
おっけーっぽい。
演習2。validationの追加。
app/models/micropost.rb
class Micropost < ApplicationRecord belongs_to :user validates :content, length: { maximum: 15}, presence: true end
おっけー。
演習3。Userにも存在チェックを追加
app/models/user.rb
class User < ApplicationRecord has_many :microposts validates :name, presence: true validates :email, presence: true end