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

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

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

Ruby on Rails 5は、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

Ruby

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

Q&A

解決済

2回答

1088閲覧

通知テーブルに一部のデータのみ保存されない。

punchan36

総合スコア105

Ruby on Rails 5

Ruby on Rails 5は、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

Ruby

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

0グッド

0クリップ

投稿2020/11/26 11:23

編集2020/11/30 05:45

前提・実現したいこと

「いいね」、「コメント」、「フォロー」のアクションがあった際に関連して、通知機能を実装しています。
Qiita123を参考に「いいね」と「フォロー」があった際の通知は既に上手く機能しました。

しかし「コメント」をもらった場合のみ、通知テーブルにそのデータが保存されません(もちろんコメントテーブル自体には保存されています)。エラーメッセージは表示されません。

参考にしたサイトと自身のカラム名の違いなどにも当然注意しながら実装しましたが、問題点が分かりませんでした。どなたかお知恵をお貸し頂ければ有難いです。

Schema.rb

Ruby

1ActiveRecord::Schema.define(version: 2020_11_24_045031) do 2 3 create_table "comments", force: :cascade do |t| 4 t.integer "user_id" 5 t.integer "post_id" 6 t.text "body" 7 t.datetime "created_at", null: false 8 t.datetime "updated_at", null: false 9 end 10 11 create_table "notifications", force: :cascade do |t| 12 t.integer "visitor_id", null: false 13 t.integer "visited_id", null: false 14 t.integer "post_id" 15 t.string "action", default: "", null: false 16 t.boolean "checked", default: false, null: false 17 t.datetime "created_at", null: false 18 t.datetime "updated_at", null: false 19 t.integer "comment_id" 20 t.index ["comment_id"], name: "index_notifications_on_comment_id" 21 t.index ["post_id"], name: "index_notifications_on_post_id" 22 t.index ["visited_id"], name: "index_notifications_on_visited_id" 23 t.index ["visitor_id"], name: "index_notifications_on_visitor_id" 24 end 25 26end

Notification.rb

Ruby

1class Notification < ApplicationRecord 2 belongs_to :post, optional: true 3 belongs_to :comment, optional: true 4 5 belongs_to :visitor, class_name: 'User', foreign_key: 'visitor_id', optional: true 6 belongs_to :visited, class_name: 'User', foreign_key: 'visited_id', optional: true 7end

Comment.rb

Ruby

1class Comment < ApplicationRecord 2 validates :body, {presence: true} 3 4 belongs_to :user 5 belongs_to :post 6 7 has_many :notifications, dependent: :destroy 8 9 def create_notification_comment!(current_user, comment_id) 10 temp_ids = Comment.select(:user_id).where(post_id: id).where.not(user_id: current_user.id).distinct 11 temp_ids.each do |temp_id| 12 save_notification_comment!(current_user, comment_id, temp_id['user_id']) 13 end 14 save_notification_comment!(current_user, comment_id, user_id) if temp_ids.blank? 15 end 16 17 def save_notification_comment!(current_user, comment_id, visited_id) 18 notification = current_user.active_notifications.new( 19 post_id: id, 20 comment_id: comment_id, 21 visited_id: visited_id, 22 action: 'comment' 23 ) 24 if notification.visitor_id == notification.visited_id 25 notification.checked = true 26 end 27 notification.save if notification.valid? 28 end 29end

Routes.rb

Ruby

1 get 'notifications/index' => 'notifications#index'

Notification_controller.rb

Ruby

1class NotificationsController < ApplicationController 2 3caches_action :index 4 def index 5 @notifications = @current_user.passive_notifications.includes([:visitor]).order(created_at: :desc).page(params[:page]).per(20) 6 @notifications.where(checked: false).each do |notification| 7 notification.update_attributes(checked: true) 8 end 9 end 10end

Comments_controller.rb

Ruby

1class CommentsController < ApplicationController 2 def create 3 @comment = Comment.new(comment_params) 4 @post = @comment.post 5 Comment.create(body: comment_params[:body], post_id: params[:post_id], user_id: @current_user.id) 6 if @comment.save 7 @post.create_notification_comment!(@current_user, @comment.id) 8 else 9 redirect_back(fallback_location: post_comments_path) 10 end 11 end 12end

Notifications/index.html.erb

Rails

1<div class="notification"> 2 <h1>Notifications</h1> 3</div> 4 5<% if @notifications.exists? %> 6 <div class="users-index"> 7 <%= render @notifications %> 8 </div> 9<% else %> 10 <p>通知はありません</p> 11<% end %>

_notification.html.erb

Rails

1<div> 2 <%= notification_form(notification) %> 3 <span><%= "(#{time_ago_in_words(notification.created_at)} ago)" %></span> 4 <br> 5 <% if !@comment.nil? %> 6 <p class="moderate-font text-center" style="color: #C0C0C0;"><%= @comment %></p> 7 <% end %> 8</div>

helpers/notifications_helper.rb

Ruby

1module NotificationsHelper 2 def notification_form(notification) 3 @visitor = notification.visitor 4 @comment = nil 5 your_item = link_to 'あなたの投稿', post_path(notification), style:"font-weight: bold;" 6 @visitor_comment = notification.comment_id 7 case notification.action 8 when "follow" then 9 tag.a(notification.visitor.name, href:user_path(@visitor), style:"font-weight: bold;")+"があなたをフォローしました" 10 when "like" then 11 tag.a(notification.visitor.name, href:user_path(@visitor), style:"font-weight: bold;")+"が"+tag.a('あなたの投稿', href:post_path(notification.post_id), style:"font-weight: bold;")+"にいいねしました" 12 when "comment" then 13 @comment = Comment.find_by(id: @visitor_comment)&.body 14 tag.a(@visitor.name, href:post_path(@visitor), style:"font-weight: bold;")+"が"+tag.a('あなたの投稿', href:post_path(notification.post_id), style:"font-weight: bold;")+"にコメントしました" 15 end 16 end 17end

補足情報(FW/ツールのバージョンなど)

ruby 2.6.4p104
RubyGems 3.0.3
Rails 5.2.3

追記 post.rb

class Post < ApplicationRecord validates :title, {presence: true, length: {maximum: 50}} # validates :level, {presence: true} # validates :maximum, {presence: true} # validates :message, {presence: true, length: {maximum: 140}} # validates :user_id, {presence: true} belongs_to :user has_many :likes, dependent: :destroy has_many :comments, dependent: :destroy def user return User.find_by(id: self.user_id) end has_many :notifications, dependent: :destroy def create_notification_like!(current_user) temp = Notification.where(["visitor_id = ? and visited_id = ? and post_id = ? and action = ? ", current_user.id, user_id, id, 'like']) if temp.blank? notification = current_user.active_notifications.new( post_id: id, visited_id: user_id, action: 'like' ) if notification.visitor_id == notification.visited_id notification.checked = true end notification.save if notification.valid? end end def create_notification_comment!(current_user, comment_id) temp_ids = Comment.select(:user_id).where(post_id: id).where.not(user_id: current_user.id).distinct temp_ids.each do |temp_id| save_notification_comment!(current_user, comment_id, temp_id['user_id']) end save_notification_comment!(current_user, comment_id, user_id) if temp_ids.blank? end def save_notification_comment!(current_user, comment_id, visited_id) notification = current_user.active_notifications.new( post_id: id, comment_id: comment_id, visited_id: visited_id, action: 'comment' ) return if notification.visited_id == notification.visitor_id if notification.visitor_id == notification.visited_id notification.checked = true end notification.save if notification.valid? end end

Commentテーブルのデータベースの中身

[27] pry(main)> Comment.all Comment Load (0.4ms) SELECT "comments".* FROM "comments" +----+---------+---------+------+-------------------------+-------------------------+ | id | user_id | post_id | body | created_at | updated_at | +----+---------+---------+------+-------------------------+-------------------------+ | 1 | 23 | 2 | hoge | 2020-11-29 09:09:27 UTC | 2020-11-29 09:09:27 UTC | | 2 | 23 | 2 | huga | 2020-11-29 09:10:10 UTC | 2020-11-29 09:10:10 UTC | +----+---------+---------+------+-------------------------+-------------------------+ 2 rows in set [28] pry(main)> Comment.last(2).pluck(:body) Comment Load (0.6ms) SELECT "comments".* FROM "comments" ORDER BY "comments"."id" DESC LIMIT ? [["LIMIT", 2]] => ["hoge", "huga"] [29] pry(main)>

###【追記2】ストロングパラメータ変更後

comments.controller.rb内のストロングパラメータを変更しました。

Ruby

1 @comment = Comment.new(comment_params) 2 @post = @comment.post 3 4 Comment.create(body: comment_params[:body], post_id: params[:post_id], user_id: @current_user.id) 5 if @comment.save! 6 @post.create_notification_comment!(@current_user, @comment.id) 7 redirect_back(fallback_location: post_comments_path) #save出来ても出来なくても、以下のルートにリダイレクト。 8 else 9 redirect_back(fallback_location: post_comments_path) 10 end 11 end 12 13def comment_params 14 params.require(:comment).permit(:body) 15end 16 17↓ # comment_paramsの中身のみ変更。 18 19def comment_params 20 params.require(:comment).permit(:body).merge(post_id: params[:post_id], user_id: @current_user.id) 21end

するとコメントを送信する度に2重に保存されるようになった(つまりcomment_paramsが機能する様になった)ので、以下の1行を消す事でコメントが通常通り保存されるようになりました。

Comment.create(body: comment_params[:body], post_id: params[:post_id], user_id: @current_user.id)

それでも通知テーブルにコメントのデータは保存されず、コマンドにて以下のエラーが出ました。

NoMethodError (undefined method `create_notification_comment!' for #<Post:0x000000000f0c16b0> Did you mean? create_notification_like!):

どうやらcreate_notification_comment!post.rb内に記述しないといけない(?)ようだったので、定義をcomment.rbからpost.rbに移行させました。これにより、post.rb内でのcommentに関する記述は以下の一行のみになりました。

has_many :notifications, dependent: :destroy

するとようやく、コメントを送信後、通知テーブルにそのデータが保存されるようになりました。またビューのnotifications/indexでもしっかり通知が呼び出されました。

しかしあと2点だけ問題が出てきました。

  1. コメントを削除しても通知のデータが残ったままになる(dependent: :destroy)が機能しない。
  2. ログイン中のユーザーのコメントも、本人の通知に表示されてしまう。

2に関して、actiontrueで保存されているので、保存のされ方は問題ないかと思います。後はビュー内でも、本人には通知がいかないようにする旨の記述を加える必要があると言う事でしょうか?

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

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

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

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

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

neko_daisuki

2020/11/27 03:43

comment.rb の notification.save if notification.valid? を notification.save! に書き換え、コメントを保存するととエラーが表示されませんか? エラーが出たらそのエラーを追記してください。
punchan36

2020/11/27 04:43

有難うございます。 特にエラーは表示されませんでした。コードを書き換えた後ですが、①コメントがコメントテーブルに保存される。②コメントが通知テーブルには保存されない。の流れも書き換え前と同じでした…。
neko_daisuki

2020/11/27 05:04

def save_notification_comment! の notification.save if notification.valid?の次の行に binding.pry を挿入し、 notification.errors と打つと何か表示されないでしょうか
punchan36

2020/11/27 05:26

ブレークポイントを指定してもpryが作動しませんでした…。ビューファイルの適当な箇所では作動したのですが、notification.save if notification.valid?の前後の行どちらにbinding.pryを置いても反応無しです。 これ自体おかしな事なのでしょうか…。
neko_daisuki

2020/11/27 05:37

CommentsController#create で @post.create_notification_comment! となってますね。 これは @comment..create_notification_comment! じゃないのかな・・・ エラーが出ないということは、post.rb にも create_notification_comment! メソッドがあるんでしょうか。
punchan36

2020/11/27 05:56

@comment.create_notification_comment!に変えても結果は同じでした。 ただ「comment」は「post」とアソシエーションの関連がありますので、@post = @comment.postと上の行で記述しているように、@post.create_notification_comment!と言う記述は合っているのかなと思いました(参考記事もどこも同じ記述でしたので…)。 またpost.rbには、いいねが押された場合の為にcreate_notification_like!の記述はあります。 追記も致しましたので、なかなか解決せず申し訳ありませんが引き続きご教授頂けると有難いです。
neko_daisuki

2020/11/27 06:10

追記のメソッドがcreate_notification_like!になってますが、 postにもcomment#create_notification_comment! と同じようなメソッドがあるとして、 今度はpost#save_notification_comment! で binding.pry してみてください。 たぶん notification.valid? が falseになっていて save されてないんじゃないかと思います。
punchan36

2020/11/29 07:41

create_notification_like!の中身はcreate_notification_comment!とはやや違いますが、post.rbにcreate_notification_comment!の中身を書き加えると言う事でしょうか。申し訳ありません。
neko_daisuki

2020/11/29 08:04

CommentsControllerで @post.create_notification_comment! としているので、 すでにpostにcreate_notification_comment!が存在すると思ったのですが、存在しないのでしょうか。 存在しないならエラーになるはずです。 post#create_notification_comment! を調べれば解決できそうです。
punchan36

2020/11/29 08:21

post.rbにあるcommentに関する記述は「has_many :comments, dependent: :destroy」のみで、「create_notification_comment!」の記述はありません。いいねがあった時用の「create_notification_like!」はpost.rbに記述していますが…。 「create_notification_comment!」はあくまでcomment.rbにのみ記述しています。エラーが出てくれれば解決の糸口になりそうな気がするのですが…。
neko_daisuki

2020/11/29 08:27

もしかして、@comment.save に失敗しているのでは。 コメントの投稿が成功しているように見えるのは、 Comment.create(body: comment_params[:body], post_id: params[:post_id], user_id: @current_user.id) この行でコメントを作成しているからで、@comment.saveはfalseになってるのではないかと。
punchan36

2020/11/29 08:46

データベースにて「Comment.all」を入力すると一覧がきちんと表示されます。ですので@comment.saveは機能しているのではないでしょうか。また「@comment.save!」とbinding.pryの記述を加えてみても、コメント送信時にエラー等は表示されません。 「データベースで確認できるけれども実際は失敗している」と言うような事もあるのでしょうか…?
neko_daisuki

2020/11/29 09:01

データベースに同じbodyのコメントが連続でふたつあるのでしょうか? コンソールで Comment.last(2).pluck(:body) として確認してみてください。 @comment.save!でエラーにならないということは、 存在しない@post.create_notification_comment! が呼ばれて エラーになるはずなのですがエラーにならない。不思議です。
punchan36

2020/11/29 09:14

「同じbodyのコメントが連続でふたつ」…と言うのはよく分かりません。データベースを見る限りそんな事ははいかと思います。 追記致しましたが、コメントテーブルのデータベースの中身は至って普通に見えます…。糸口がつかめないので非常に苦しいです。。何度もお付き合いいただいているのに申し訳ありません。
neko_daisuki

2020/11/29 09:20

@comment = Comment.new(comment_params)と、 Comment.create(body: comment_params[:body], post_id: params[:post_id], user_id: @current_user.id) は同じ body を保存しているはずです。 なので、@comment.save が正しく保存(true)されているのなら、同じコメントが連続すると思いました。 連続していないようなので、保存されていないんじゃないかなぁ。 Comment.create(body: comment_params[:body], post_id: params[:post_id], user_id: @current_user.id) の行をコメントアウトすると@comment.saveがtrueになり、 @post.create_notification_comment! でエラーになると思うのですが、どうでしょうか。
punchan36

2020/11/29 09:52

その行をコメントアウトしてもエラーにはなりませんでした…。単純にコメントが保存されず、ページが遷移されただけです。 comments.controller.rbに実は以下のストロングパラメータも記述しているのですが、こちらは特に関係ないでしょうか? def comment_params params.require(:comment).permit(:body) end
neko_daisuki

2020/11/29 09:57

comment.rb に belongs_to :user belongs_to :post とありますが、rails5からはデフォルトでrequired: trueなはずです。 なので、この comment_paramsでは保存されませんね。 params.require(:comment).permit(:body).merge(post_id: params[:post_id], user_id: @current_user.id) としてみてください。 これで@comment.saveで保存されるはずです。
punchan36

2020/11/29 11:53

有難うございます!!かなり進める事が出来ました。 今後質問する際は、明らかに質問と関係のない記述等は省くとして、ストロングパラメータの内容等は残して投稿するよう心掛けます。 大分解決に近付けたのですがあと数点だけ問題がありますので、可能であればご助言頂けませんでしょうか。
neko_daisuki

2020/11/29 21:08

1.コメントを削除しても通知のデータが残ったままになる(dependent: :destroy)が機能しない。 コメントのIDは正しく保存されているように見えます。 なので消えるはずなのですが、どうやって確認されましたか? コメントを削除すると以下のようなログは出ませんか? Notification Load (0.4ms) SELECT `notifications`.* FROM `notifications` WHERE `notifications`.`comment_id` = 2 Notification Destroy (0.4ms) DELETE FROM `notifications` WHERE `notifications`.`id` = 1 Notification Destroy (0.3ms) DELETE FROM `notifications` WHERE `notifications`.`id` = 2 Notification Destroy (0.2ms) DELETE FROM `notifications` WHERE `notifications`.`id` = 3 Comment Destroy (0.2ms) DELETE FROM `comments` WHERE `comments`.`id` = 2 あと、notification に cache_action :index とあるのが気になります。 2.ログイン中のユーザーのコメントも、本人の通知に表示されてしまう。 自分自身がコメントしたと通知欄に表示されてしまうということでしょうか。 自分以外に post にコメントしたユーザー(temp_ids)が存在する場合は、自分には通知されないと思うのですが、 それがいない場合は post の user に通知されるようです。 なので、post の user が current_user の場合、自分に通知されます。 それが嫌なら validation で弾くか、 Notification validates :visitor_id, uniqueness: { scope: [:visited_id] } notification.save の前に以下のようにすると良いのでは return if notification.visited_id == notification.visitor_id
punchan36

2020/11/30 05:41

有難うございます! 1. dependent: :destroyが機能しない点ですが、ターミナルでコメントを「Comment.destroy_all」すると以下のログが出ます。 --------------------------------------------------------------------------------------------- Comment Load (7.1ms) SELECT "comments".* FROM "comments" WHERE "comments"."id" = ? LIMIT ? [["id", 2], ["LIMIT", 1]] (2.3ms) begin transaction Comment Destroy (3.4ms) DELETE FROM "comments" WHERE "comments"."id" = ? [["id", 2]] (42.8ms) commit transaction --------------------------------------------------------------------------------------------- 関連付けているはずのNotificationの情報は出力されず、notifications/index(ビュー上)でも「**があなたの投稿にコメントしました (** minutes ago)」と、通知の表示が残ってしまいます。コメント自体はビュー上でももちろん消えている状態です。 また「cache_action :index」は消し忘れのコードでした。こちらを消しても上記の様に動いてしまいます。 2. 自分自身がコメントしたと通知欄に表示されてしまう点ですが、直りました!ご助言を頂いた通り、 return if notification.visited_id == notification.visitor_id を入れる事で問題が回避出来ました。重ね重ね有難うございます。
punchan36

2020/11/30 07:33

修正すべき細かい点はいくつか残っておりますが、本題は解決致しました。有難うございました! 何度もやり取りして頂いたのでベストアンサーにさせて頂きたいので、回答欄に何かコメント頂けませんでしょうか。
guest

回答2

0

ベストアンサー

dependent: :destroyの件は解決できずに残念です。
さいあく、comment.rb に

after_destroy do self.notifications.destroy_all end

で削除されると思います。

投稿2020/11/30 08:38

neko_daisuki

総合スコア2090

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

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

punchan36

2020/11/30 12:01

有難うございます! Twitterがどのようになっているか確かめてみましたが、似たような部分もありました。 (follow→unfollow→followをした場合。最初の通知が残ったままになり、再度followしても新しい通知は来ない、等) 取りあえず最低限の機能は果たしておりますので、細かな点は追々実装していければと思います。今回は長く付き添って頂き有難うございました!
guest

0

Notification には実在するcommentのidが必須です

class Notification < ApplicationRecord belongs_to :post, optional: true belongs_to :comment, optional: true

しかしそれが与えられて居ません

notification = current_user.active_notifications.new( post_id: id, visited_id: user_id, action: 'like' )

のでsaveしません

投稿2020/11/28 23:46

winterboum

総合スコア23329

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

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

punchan36

2020/11/29 07:44

ご回答有難うございます。 ご指摘頂いたPost.rbに書いておりますのは、「いいね」が押された場合の通知機能の記述(create_notification_like!)です。問題の「コメント」が送信された場合の通知機能はComment.rbに書いており、comment_id: comment_idの記述はしております。
winterboum

2020/11/29 13:10

model Post を載せてください
winterboum

2020/11/29 13:15

違和感を感じるのは いいね はpostに処理させ、CommentはCommentに処理させるという一貫性の違和感。 いいねのcreateが成功したら、いいねに, comment のcccreateに成功したらcommentに、 お知らせさせるのが、、、 もしくは共にPostにさせる。 Postに「ぼくいいねされちゃった」と言わせるより いいね に いいねしたよ って言わせるほうが自然じゃないかな
winterboum

2020/11/29 23:19

model Postの validatioとか関連定義をみたいのですが
punchan36

2020/11/30 05:56

有難うございます!post.rbの中身を、定義も含めて全て書き出しました。 コメント情報が通知テーブルに保存されない点ですが、comment.controller.rbにありますストロングパラメータに問題がありました。 もうお一方コメントを頂いた方のご助言で色々と問題が発覚しまして、winterboumさまも仰るように、「いいねの通知」「コメントの通知」処理の両方をpost.rbに記述する事で上手く動くようになりました。有難うございます。 ただ、コメントを削除しても通知のデータが残ったままになる(dependent: :destroyが機能しない)問題だけまだ残っておりますので、そこだけ分かり次第問題を解決済みにさせて頂きます。申し訳ありません。
neko_daisuki

2020/11/30 06:25

Post has_many :notifications, dependent: :destroy となってますが、Post の削除ではnotificationが削除されますか? データを削除して作り直すのが面倒な場合、 bin/rails c --sandbox とやると、コンソール終了時にデータが元に戻ります。
punchan36

2020/11/30 06:53

はい、ちゃんと削除されます。整理しますと、この周りでの「has_many (dependent: :destroy)」関連は以下の5つがあります。 1. Post has_many comments(投稿を削除すれば、関連のコメントデータも消える。) 2. Post has_many likes(投稿を削除すれば、関連のいいねデータも消える。) 3. Post has_many notifications(投稿を削除すれば、関連の通知データも消える。) 4. Comment has_many notifications(コメントを削除すれば、該当の通知データも消える。) 5. Like has_many notifications(いいねを削除すれば、該当の通知データも消える。) 1, 2, 3は上手くいきますが、4, 5が残ってしまいます。これってコントロール出来るのか、それともある程度仕方ないものなのでしょうか…。
winterboum

2020/11/30 07:05

それが原因とは思いませんが、ちと変 「それ」⇐ Comment has_ONE notification なのでは?
punchan36

2020/11/30 07:31

winterboumさま 有難うございます。そうですね。 複数のユーザーがコメントしても通知は1通ですので、確かにhas_oneが正しいです!
punchan36

2020/11/30 12:03

winterboumさま この度はご回答有難うございました! 別の回答者様がかなり長いやり取りに付き添って下さいましたので、そちらをベストアンサーに選ばせて頂きました。申し訳ありません。 いつも有難うございます。また機会がありましたら宜しくお願い致します!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問