Rails Diary

プログラミングの学習記録です。

RUNTEQ記録(9)rails console

*今日やったこと

rails console課題

①作業用のアプリ作成

rails _バージョン_ new アプリ名

 

②所定のテーブル作成

rails g model モデル カラム1:データ型 カラム2:データ型・・・

 

❸DB Browser for SQLiteをインストール

データベースの中身を確認できる

 

課題に入る

ProgateのSQL

課題3までは特に躓く要素がなかったので、サクサクできたのですが、課題4のテーブルの結合の仕方を求めて、何となくSQLのjoinを思い出したので、ProgateのSQL課題を全てやり直して見ましたが特に使う箇所がなかったですね。

 

せっかくやったのでSQL備忘録(少し)

「データを取得してください」

データベースに送る命令(クエリ)

クエリを書く言語=SQL

 

whereで条件検索 whereの検索対象は全体

group byでグループ化

sumなどの関数実行

グループ化した後の条件指定はhaving havingの検索対象はグループ化されたデータ

 

実行順序

fromでテーブル指定

複数テーブルがあればjoin,onで結合

whereで取得条件

グループ化 group by

関数実行 sum, count,avg,max,min

havingでグループ化したデータに対して条件検索

検索 select, distinct

順序 order by

limit指定

 

課題の解答動画を見る

テーブルの結合をrails consoleだけで完結させることが出来ずに、解答動画を確認。

rails consoleで完結させることしか頭になく、設定ファイルをいじってはいけない縛りかと思っていました😓)

 

データを関連付ける必要があるので、idのデータ型はreferences

まず、自分は講師の方が指摘していた良くないやり方でテーブルを作成していました。

良くないやり方「rails g model Task name:string user_id:integer

自分が入力したコード「rails g model Task name:string user_id: bigint」

 

確かに事前準備の指示に不穏な箇所、「user_id : bigint(reference)」みたいな書き方がされていたけど、括弧書きだからいいかとスルーしていました。初見殺しだ・・・笑

 

テーブルの内容を変更しようと試みる

テーブルの内容の変更ってどうやるんだっけ?

どうやるんだっけ?が渋滞している😰

 

書籍の思い当たるところとWeb検索で一度カラムを削除し、新しく追加するやり方を知る

 

①削除用のファイルを作成し、中身を書き換える

$rails g migration RemoveUserIdColumnFromTasks

 

def change

 remove_column :tasks, :user_id, :bigint

end

 

$rails db:migrate

 

②追加用のファイルを作成、中身変更

$rails g migration AddUserColumnToTasks

 

def change

 add_column :tasks, :user, ;reference

end

 

$rails db:migrate

 

なんかエラーが出てきた

-- add_column(:Tasks, :user, :references)

rails aborted!

StandardError: An error has occurred, this and all later migrations canceled:

(エラーが発生したので以降の操作を全てキャンセルしたよ的なエラー)

 

よく分からないので、今の状況を確認

$rails db:migrate:status

 

database: /Users/****/workspace/runteq/rails_introduction_2/rails_console_app/db/development.sqlite3

 

 Status   Migration ID    Migration Name

--------------------------------------------------

   up     20211204011718  Create users

   up     20211204012806  Create tasks

   up     20211204035958  Create categories

   up     20211204040115  Create task categories

   up     20211204043359  Remove user id column from tasks

  down    20211204043754  Add user id column to tasks

 

追加だけできていないことだけは分かった。

色々調べて見たけど、タイプミスではなさそう?

 

http:// https://qiita.com/naokishizuka/items/e51b5ea9ec56dd0471f7

↑のサイトを発見

 

Rails5では、デフォルトで作成されるidがbigintになっているそう

参照元テーブルのカラムをintegerで作成すると良くないことが起きるらしい

・foreign keyとやらが作成されないので、テーブルのカラムをbigintで作成しようね

 

そして、下記のどちらでも変わらなそうなことが書かれていた・・・

def change

 add_column :tasks, :user_id, :bigint

end

 

def change

 create_tables :tasks do |t|

 t.references :user

end

 

そもそも、削除したり再度追加したりする必要はない?

 

とりあえず、先に進めるために前者の方で進めることに・・・

(エラーが出て進めなくなった場合は、テーブルを作り直すつもりでしたが案の定上手く行かなくなりアプリを作り直しました)

 

user.referencesでテーブルを作っていれば、自動的に入力されているという「belongs_to :user」はapp>models>task.rbの中に記載されていなかった。

このため、手動で入力をする

class Task < ApplicationRecord

 belong_to :user

end

 

そして、なんやかんや進めていき、

TaskCategory.create(task: task1, category: benkyo)

TaskCategory.create(task: task2, category: benkyo)

TaskCategory.create(task: task3, category: zatuji) 

TaskCategory.create(task: task4, category: goraku) 

 

中間テーブルを実行しようとすると、エラーが出てきました。

 

エラー発生

ActiveModel::UnknownAttributeError (unknown attribute 'task' for TaskCategory.)

(TaskCategoryにtask属性がない)

 

ここら辺から、事前準備の弊害と思しきエラーが見られるように・・・

 

確かに、テーブル作成時に、「rails g model Task name:string task:references」という作り方をしていないため、taskという属性はないという指摘は分かる気がする。

 

もう一つのやり方を試すことに、

task_idとcategory_idを使います。

TaskCategory.crate(task_id: 1, category_id: 2)

   (0.1ms)  begin transaction

  TaskCategory Create (5063.7ms)  INSERT INTO "task_categories" ("task_id", "category_id", "created_at", "updated_at") VALUES (?, ?, ?, ?)  [["task_id", 1], ["category_id", 2], ["created_at", "2021-12-04 07:21:03.957653"], ["updated_at", "2021-12-04 07:21:03.957653"]]

   (0.1ms)  rollback transaction

Traceback (most recent call last):

        2: from (irb):36

        1: from (irb):37:in `rescue in irb_binding'

ActiveRecord::StatementInvalid (SQLite3::BusyException: database is locked: INSERT INTO "task_categories" ("task_id", "category_id", "created_at", "updated_at") VALUES (?, ?, ?, ?))

 

二つ目のやり方では、ロールバックされてしまいました。

分解してやってみると、saveができていない様です。

 

 

振り出しに戻る

動画の指定通りにテーブルを作成しました。

idのデータ型をreferencesにして作成

 

user=User.new(name: “あや”, age: 🥺)

user.save

自分は上のように2行で書いていたけれど、createで1行でかける

user = User.create(name: “太郎” age: 12)

 

アソシエーションの設定をいじる

task.rbとuser.rbの中身を変更

前述したuser.referencesでテーブルを作っていれば、自動的に入力されているという「belongs_to :user」は今回はしっかり書いてありました。

【task.rb】

class Task < ApplicationRecord
belongs_to :user
end

【user.rb】

class User < ApplicationRecord
has_many :tasks, dependent: :destroy
end

↑dependent: :destroyは紐づけたテーブルでも削除すると連動してレコードが消えるというやつ

 

class CreateTasks < ActiveRecord::Migration[5.2]
def change
create_table :tasks do |t|
t.string :name
t.references :user, null: false, foreign_key: true

t.timestamps
end
end
end

↑課題後に眺めていて気が付いたが、同じやり方でテーブルを作ったものの自分のマイグレーションファイルにはNOT NULL制約がなかった。あとから追加するやり方で追加すれば良いんだろうけど、なぜあらかじめ入っていないのかは分からない。

 

タスクを作る

user = User.find(1) でユーザーを検索

ArgumentError (The :dependent option must be one of [:destroy, :delete_all, :nullify, :restrict_with_error, :restrict_with_exception], but is :destory)

いきなりエラー発生

dependentオプションが下記の内の一つに違いない

class User < ApplicationRecord

  has_many :tasks, dependent: :destory

end

 

スペルミスでした。

分かりやすいエラー親切や・・・

 

userと関連付けてタスクを作成する

user=User.find(1)

user.tasks.create(name: “Rubyを勉強する”)

ちなみに私は二流(Task.create(name: “勉強” user_id: 1))でした笑

 

userと関連付けてタスクを作成することでuserに紐づいたタスクが作られる

オブジェクトを指定して作成することもできる

Task.create(name: “本を読む”, user: user)

 

カテゴリ作成

Category.create(name: “趣味”)

特定のIDを決めて紐付けるやり方だと、多対一の関係で、柔軟性があるとは言えない。

中間テーブルを作って紐づけた方が良い。

 

①タスクを取ってくる

task1=Task.find(1)

task2=Task.find(2)

task3=Task.find(3)

 

②Category.allでカテゴリのIdを確認

zatuji=Category.find(1)

benkyo=Category.find(2)

goraku=Category.find(3)

 

外部キーが二つある場合はいきなりモデル.createでもいい

 

TaskCategory.create(task: task1, category: benkyo)

TaskCategory.create(task: task2, category: benkyo)

TaskCategory.create(task: task3, category: zatuji) 

 

DB Browser for SQLiteでちゃんと関連付けたテーブルができたか確認

大丈夫でした!!

 

感想

最初から、解答を見るのは駄目だと思って、分からない箇所は調べて進めているものの、自分が検討違いなことを調べてどんどん斜め後ろに後退していることに、解答を見て初めて気が付きます。

これも勉強というか経験だなと思いつつ、カリキュラムの進度がどんどん悪化しているので、ある程度で見切りをつけるべきなんだろうとも思います。

プログラミングを勉強したい自分と、受講期間に追われている感覚で焦燥感ばかりになっている自分がいる感じ😔踏ん張る