コメント機能を追加するときのポイント
私が作成しているアプリケーション「Yamashiru」を受けて気になった点や復習した方が今後の役に立つと思って作成しています。
さらにエンジニア初心者の方に向けて タメになる情報をお届けします。
今回は、、、
コメント機能を追加するときのポイント
今回のケースは投稿に対してコメント機能を加える際の注意点についてまとめました。
dependent: :destroy について
dependent: :destroyを追加することで、 親モデルを削除する際に、その親モデルに紐づく「子モデル」も一緒に削除できるようになります。 今回の私のケースですと親モデル=投稿機能、子モデル=コメント機能になります。よって投稿が削除されると コメントも削除されるということになります。
tweetモデル
class Tweet < ApplicationRecord <中略> has_many :comments, dependent: :destroy
commentモデル
class Comment < ApplicationRecord <中略> belongs_to :tweet
その際にルーティングもネストされているか確認します。
routes.rb
resources :tweets do resources :comments, only: :create end
いかがでしたでしょうか? 1個ずつ落ち着いて実施出来れば簡単な操作になりますので是非ご活用下さい!
DBにデータが登録されない時の対処(エラーが出ない)
私が作成しているアプリケーション「Yamashiru」を受けて気になった点や復習した方が今後の役に立つと思って作成しています。
さらにエンジニア初心者の方に向けて タメになる情報をお届けします。
今回は、、、
DBにデータが登録されない時の対処
今回のケースは今まで画像投稿が出来ていたのに突然DBに保存できなくなってしまった時の対処方法についてまとめました。
問題点を確認
エラーが出ない場合はbinding.pryを活用します。今回のポイントは「tweetで保存(create)しようとしたが出来なかった」です。
Gemfile
gem 'pry-rails'
tweets_controller.rb
def create binding.pry #ここに入れます @tweet = Tweet.new(tweet_params) if @tweet.save redirect_to root_path else render :new end end
ターミナル
13: def create => 14: binding.pry 15: @tweet = Tweet.new(tweet_params) 16: if @tweet.save 17: redirect_to root_path 18: else 19: render :new 20: end 21: end [1] pry(#<TweetsController>)> params => <ActionController::Parameters {"authenticity_token"=>"nHTZ+u5/93ovBjChsu26SBv8hlSqSGJBRBzMzKoscajUOaCI2sikOtszQsGqjSnI0mU4AN2+DDEiJQ+1G9ca2g==", "tweet"=>{"image"=>#<ActionDispatch::Http::UploadedFile:0x00007f8487626c78 @tempfile=#<Tempfile:/var/folders/z5/hwd0zxps2ld2xpsfx_6bjb6c0000gn/T/RackMultipart20210729-2283-1c34iv8.jpg>, @original_filename="pexels-dziana-hasanbekava-5589435.jpg", @content_type="image/jpeg", @headers="Content-Disposition: form-data; name=\"tweet[image]\"; filename=\"pexels-dziana-hasanbekava-5589435.jpg\"\r\nContent-Type: image/jpeg\r\n">, "title"=>"大パノラマ", "theme_id"=>"4", "prefecture_id"=>"6", "mountain_name_id"=>"4", "climbing_time_id"=>"5", "stamina_id"=>"4", "mountain_view_id"=>"3", "danger_id"=>"2"}, "commit"=>"SEND", "controller"=>"tweets", "action"=>"create"} permitted: false> [2] pry(#<TweetsController>)> tweet_params User Load (0.5ms) SELECT `users`.* FROM `users` WHERE `users`.`id` = 2 ORDER BY `users`.`id` ASC LIMIT 1 ↳ app/controllers/tweets_controller.rb:34:in `tweet_params' => <ActionController::Parameters {"image"=>#<ActionDispatch::Http::UploadedFile:0x00007f8487626c78 @tempfile=#<Tempfile:/var/folders/z5/hwd0zxps2ld2xpsfx_6bjb6c0000gn/T/RackMultipart20210729-2283-1c34iv8.jpg>, @original_filename="pexels-dziana-hasanbekava-5589435.jpg", @content_type="image/jpeg", @headers="Content-Disposition: form-data; name=\"tweet[image]\"; filename=\"pexels-dziana-hasanbekava-5589435.jpg\"\r\nContent-Type: image/jpeg\r\n">, "title"=>"大パノラマ", "theme_id"=>"4", "prefecture_id"=>"6", "mountain_name_id"=>"4", "climbing_time_id"=>"5", "mountain_view_id"=>"3", "stamina_id"=>"4", "danger_id"=>"2", "user_id"=>2} permitted: true>
ターミナル
[1] pry(#<TweetsController>)> @tweet.image => #<ActiveStorage::Attached::One:0x00007f8483e83aa0 @name="image", @record= #<Tweet:0x00007f848780cd58 id: nil, title: "テスト", theme_id: 4, prefecture_id: 6, climbing_time_id: 5, mountain_view_id: 3, stamina_id: 4, danger_id: 2, user_id: 2, category_id: nil, #不要なidが含まれていてnilになっている created_at: nil, updated_at: nil, mountain_name_id: 4>>
問題点の対処
別機能を付ける際に後にアソシエーションでcategoryを追加したことによる原因ということが判明しました。では先程のnilはどのように解消すれば宜しいでしょうか。
model/tweet.rb
<中略> belongs_to :category, optional: true #optional: true を追加
optional: trueは、belongs_toの外部キーのnilを許可するというものであり こちらでデータ登録が出来る様になりました。
いかがでしたでしょうか? 1個ずつ落ち着いて実施出来れば簡単な操作になりますので是非ご活用下さい!
カラム追加時のエラー
私が作成しているアプリケーション「Yamashiru」を受けて気になった点や復習した方が今後の役に立つと思って作成しています。
さらにエンジニア初心者の方に向けて タメになる情報をお届けします。
今回は、、、
カラムの追加の際のエラー対処
どうしてもアプリケーションを作っていく中で「こんな機能も入れたいな。」と思ってテーブルを修正される方も多いかと思います!その時に私が遭遇したエラーをご紹介します。
エラー内容
カラムを追加した後にrails db:migrateを実施したところ以下のエラーが発生しました。
-- create_table(:tweets) rails aborted! StandardError: An error has occurred, all later migrations canceled: Column `user_id` on table `tweets` does not match column `id` on `users`, which has type `bigint(20)`. To resolve this issue, change the type of the `user_id` column on `tweets` to be :bigint. (For example `t.bigint :user_id`). Original message: Mysql2::Error: Cannot add foreign key constraint <中略>
エラーとの向き合い方
ポイントはどんな文章が記載されているかを冷静に見極めることです。
気になる文章を翻訳してみます
Column `user_id` on table `tweets` does not match column `id` on `users`, which has type `bigint(20)`. To resolve this issue, change the type of the `user_id` column on `tweets` to be :bigint. (For example `t.bigint :user_id`).
テーブル `tweets` のカラム `user_id` が `users` のカラム `id` と一致しません。この問題を解決するには、`tweets` の `user_id` カラムの型を :bigint に変更します。(例えば `t.bigint :user_id`)。
エラー対処
結論、Railsでは外部キーを使用する際はreferences型を推奨しているので、bigint型を使用する必要はありません。
このエラーのポイントは参照できませんということなので、マイグレーションファイルの作成順に問題があると仮説できます。
添付画像のように数字部分を、参照される側(今回の場合categories)のテーブルよりも外部キーを使用するテーブル(今回の場合tweets)の数字を大きくすれば解決します。 こちらは手入力で変更が可能です。
20210711053719_create_tweets.rb #20210711(2021/7/11)を20210728(2021/7/28)に変更
その後に通常通りrails db:createを実施したところテーブルの修正が出来ました。
いかがでしたでしょうか? 1個ずつ落ち着いて実施出来れば簡単な操作になりますので是非ご活用下さい!
クラスとインスタンス①
自身が学んできたときになかなか言語化できなかった内容を作成しています。
今回は、、、
クラスとインスタンス
Rubyに用意された値(文字列、数値、ハッシュ、配列など)以外に新しい種類の値を作るために必要な概念です。
データの元となる設計図
値は種類毎に役割や使用できるメソッドが異なり、新しい種類の値を作る際もルールを決めておく必要があります。
クラス
属性と処理(メソッド)のルールを定義する。 (例:車の場合 クラス=ひな形=車の設計図) クラスは、共通の属性と処理を決めるだけで、実態がありません。
クラスの定義方法
class Car #クラス名は半角英数大文字 end
設計図からデータを作成
クラスから生成される、データを持ったインスタンスを作成します。
インスタンス
クラスを元にして作られるデータです。 (例:車の場合 設計図から作られて実際に販売される車) インスタンスはクラスが使用できるnewメソッドを実行して生成します。
newメソッド
使用したクラスのインスタンスを生成して返します。
newメソッドを使ってインスタンスを生成します。
class Car end fire_truck = Car.new #インスタンスを生成 puts fire_truck #インスタンスを出力
次回はクラスの中に定義するクラスメソッドとインスタンスメソッドを紹介します。
MVC
私が作成しているアプリケーション「Yamashiru」を受けて気になった点や復習した方が今後の役に立つと思って作成しています。
さらにエンジニア初心者の方に向けて タメになる情報をお届けします。
今回は、、、
MVC
基礎中の基礎ですが、アプリケーションを作成する際に常に頭でイメージしておかないと上手く記述が繋がらず、実装したい機能が反映しないことも多々あります。今のうちに言語化しておきましょう。
MVCの仕組み
MVCとは、プログラミング手法のアプローチの一種でRuby on Railsでも採用されています。 Webアプリケーションを動かすために必要な処理の一部を分類し分けることで、保守性、可読性の高いコードを維持できます。 「V」はViewの略。実際にクライアント側に表示される見た目の部分です。 「M」はModelの略。Webアプリケーションにおけるビジネスロジック(データベースから取得してきた値を加工するメソッドや、レコード検索の条件が書かれたメソッド、データを保存する前に加工するメソッドなど)を定義します。 「C」はControllerの略。クライアントからのリクエストに対して適切なレスポンスを返すことや、そのレスポンスに必要なデータの用意を行う。あくまでも用意するだけが責務なので、データの加工など複雑なロジックはControllerには書きません。
モデルの作成
% rails g model モデル名
テーブルの作成
モデルを生成時に作られるマイグレーションファイルを修正。テーブルに作成するカラムとその型を、changeというメソッドの中で指定します。
<中略> def change create_table :tweets do |t| t.string :name t.string :text <中略>
マイグレーションを実行。(=テーブルの作成)
% rails db:migrate
ルーティングを設定
Ruby on Railsには、アクションの設定が慣習的に決められており、下記の表のようなアクションが存在します。
7つのアクション
index 一覧表示 show 詳細表示 new 生成 create 保存 edit 編集 update 更新 destroy 削除
resourcesメソッドを使って7つのアクションへルーティングを自動生成します。
Rails.application.routes.draw do resources :tweets end
コントローラーの作成
% rails g controller コントローラー名
コントローラーを作成するとき、コントローラー名は複数形で命名する。
コントローラーにアクションを定義
class TweetsController < ApplicationController def index @tweets = Tweet.all end end
一例ですが、こちらはtweetsテーブルのレコードを全て代入しています。
ビューの作成
viewsディレクトリを活用しながら様々なレイアウトを作成することがで出来ます。
いかがでしたでしょうか? 1個ずつ落ち着いて実施出来れば簡単な操作になりますので是非ご活用下さい!
画像投稿
私が作成しているアプリケーション「Yamashiru」を受けて気になった点や復習した方が今後の役に立つと思って作成しています。
さらにエンジニア初心者の方に向けて タメになる情報をお届けします。
今回は、、、
画像投稿について
SNS等でよく使用される画像投稿について、今回はActive Storageというアップロードツールを使用して紹介します。
Active Storageとは
ファイルアップロード機能を簡単に実装できるGemです。指定のコマンドを実行するだけで簡単に導入が出来ます。
画像加工ツールの導入
Active Storageでファイルをアップロードして保存した後、画像を加工してから(サイズや色など)表示できるようにします。
ImageMagick
% brew install imagemagick
MiniMagick
Gemfile
gem 'mini_magick'
ImageProcessing
Gemfile
gem 'image_processing', '~> 1.2'
上記が入力終えたら
% bundle install
Active Storage
% rails active_storage:install
% rails db:migrate
画像の保存
先ほど作成したActive Storageのテーブルに、画像を保存するための実装を行います。
has_one_attached
各レコードとファイルを1対1の関係で紐づけるメソッド。
使い方イメージ
class モデル < ApplicationRecord has_one_attached :ファイル名 end
Tweetsテーブルで投稿する場合
class Tweet < ApplicationRecord belongs_to :user extend ActiveHash::Associations::ActiveRecordExtensions belongs_to :theme belongs_to :prefecture belongs_to :mountain_name belongs_to :climbing_time belongs_to :mountain_view belongs_to :stamina belongs_to :danger has_one_attached :image validates :title, :image, presence: true with_options numericality: { other_than: 1, message: "can't be blank"} do validates :theme_id validates :prefecture_id end end
アソシエーションが組めた後は画像の保存を許可するストロングパラメーターをcontrollerに記述
private def tweet_params params.require(:tweet).permit(:title, :image, :theme_id, :prefecture_id, :mountain_name_id, :climbing_time_id, :mountain_view_id, :stamina_id, :danger_id).merge(user_id: current_user.id) end
画像の表示
保存した画像をブラウザ上で表示させるために今回はRailsのヘルパーメソッドであるimage_tagを使用して、簡単に画像を参照します。
image_tag
img要素を生成するRailsのヘルパーメソッドです。
使い方イメージ
# ファイルをモデルから指定する場合 <%= image_tag モデル.画像ファイル %> <%= image_tag user.avatar %> # app/assets/ディレクトリ下の画像ファイルパスでも指定できる <%= image_tag 画像ファイルのパス %> <%= image_tag "avatar.png" %>
いかがでしたでしょうか? 1個ずつ落ち着いて実施出来れば簡単な操作になりますので是非ご活用下さい!
削除関連
私が作成しているアプリケーション「Yamashiru」を受けて気になった点や復習した方が今後の役に立つと思って作成しています。
さらにエンジニア初心者の方に向けて タメになる情報をお届けします。
今回は、、、
削除関連まとめ
モデルやテーブル、データベースなど生成してみたけど「あ、間違えてる」ってこと多々ありませんか?そんな時に「削除コマンドはなんとなく知ってるけど、押したらどうなってしまうんだろう、、、」や「コマンドで削除したり、手動で削除したりややこしい」と不安になる方も多いかと思います。そういった内容も詳しく書いていこうと思います!
データベースの削除
% rails db:drop
rails db:createで作成した際に削除するコマンドになります。
データベースの削除とマイグレーションファイルの適用を一括登録
% rails db:migrate:reset
データベースの設定は間違っていないものの、再度データベースを作り直し、既存のマイグレーションファイルを適用したい場合にとても有効なコマンドです。実際にどのような操作が行われるのか。
データベースを削除する
データベースを再度生成する
既存のマイグレーションファイルをすべて適用する
*データベースを一度削除するため、保存されているデータなどはすべて削除されます。
コントローラーの削除
% rails d controller コントローラー名
rails g controllerで作成した際に削除するコマンドになります。
モデルの削除
% rails d model モデル名
rails g modelで作成した際に削除するコマンドになります。
カラムの修正
*前提として適用済みのマイグレーションファイルを編集してはいけません。
% rails db:migrate:status #マイグレーションファイルが実行済みか確認(up、downの確認)
% rails db:rollback #マイグレーションファイルを差し戻す
*削除の場合はdownした状態で右クリック▶︎削除で手動で実施
% rails db:migrate #マイグレーションファイルのカラム名などを修正してから実行
いかがでしたでしょうか? 1個ずつ落ち着いて実施出来れば簡単な操作になりますので是非ご活用下さい!