🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
Ruby

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

Ruby on Rails 6

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

RSpec

RSpecはRuby用のBDD(behaviour-driven development)フレームワークです。

データベース

データベースとは、データの集合体を指します。また、そのデータの集合体の共用を可能にするシステムの意味を含めます

Docker

Dockerは、Docker社が開発したオープンソースのコンテナー管理ソフトウェアの1つです

Q&A

解決済

1回答

342閲覧

メッセージを受け取った時刻をDBで適宜上書きするような処理を書きたいです.

sasaharukimedes

総合スコア27

Ruby

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

Ruby on Rails 6

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

RSpec

RSpecはRuby用のBDD(behaviour-driven development)フレームワークです。

データベース

データベースとは、データの集合体を指します。また、そのデータの集合体の共用を可能にするシステムの意味を含めます

Docker

Dockerは、Docker社が開発したオープンソースのコンテナー管理ソフトウェアの1つです

0グッド

0クリップ

投稿2021/02/18 02:56

編集2021/02/26 02:41

前提・実現したいこと

RubyでWebアプリを製作中で, その中でUserモデル内に **"received_at (最後にメッセージを受け取った時間,datetime) "**というカラムを追加しました.

そいつの処理を, **ポストを受け取るたびに上書き更新される (つまり, ユーザーは一つの時刻しか持てない) **ようにしたいのですが, いまいちコードの書き方がわからないです.

該当のソースコード

users_controller.rb

def create @user = User.new(user_params) # params[:user]実装は終わっていないことに注意! #マスアサインメント脆弱性 @user.received_at = Time.current if @user.save @user.send_activation_email flash[:info] = "Please check your email to activate your account." redirect_to root_url else render 'new' end end def edit end def update if @user.update(user_params) flash[:success] = "Profile updated" redirect_to @user #更新に成功した場合に扱う else render "edit" end end

posts_controller.rb

def create @post = Post.new(post_params) @post.sender_id = current_user.id @post.receiver_id = User.where.not(id:current_user.id).order(:received_at).first.id @post.save! redirect_to posts_path end

追加情報

schema.rb

create_table "posts", force: :cascade do |t| t.string "dear" t.text "content" t.string "from" t.datetime "created_at", precision: 6, null: false t.datetime "updated_at", precision: 6, null: false t.integer "sender_id" t.integer "receiver_id" end #deviseでモデルを作っている部分は割愛 create_table "users", force: :cascade do |t| t.string "username", default: "", null: false t.date "birthday" t.datetime "received_at" end

試したこと

userコントローラ内のcreateまではかけたのですが, received_atの更新の仕方がさっぱりわかりません.

updateアクション内に記述するのかなと思いましたが, 自信がありません.

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

ruby 2.6.5
rails 6.0.3.5

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

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

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

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

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

m.ts10806

2021/02/18 03:05

received_atが更新されないケースは何がありますか?
sasaharukimedes

2021/02/18 04:44

@m.ts10806さん 質問ありがとうございます. 基本的にはありません. ポストを受け取るたびに, 「received_at」がその受け取った時刻に上書き更新されるので, 例外はすべてのユーザーに基本的にありません.
m.ts10806

2021/02/18 04:48

それならupdated_atを利用で事足りるのでは?
sasaharukimedes

2021/02/22 00:33

@m.ts10806さん 遅くなりました, updated_atをそのまま利用するということでしょうか?少しupdated_atに関して調べてみます!
m.ts10806

2021/02/22 00:44

テーブル定義でCURRENT DATETIMEとかになってればUPDATEのたびに自動で更新されます。
sasaharukimedes

2021/02/25 05:37

@m.ts10806さん ありがとうございます, 簡単なようならそっちで実装することも検討してみます!
guest

回答1

0

ベストアンサー

ポストを受け取る = Post が作成されたときとすると、
モデルに after_create を追加して更新できます。

ruby

1class Post 2 belongs_to :receiver, class_name: "User" 3 4 after_create do 5 # updated_at も更新される 6 self.receiver.update(received_at: Time.current) 7 # updated_at は更新しない 8 self.receiver.update_columns(received_at: Time.current) 9 end 10end

これだとコントローラーが簡潔で済みますが、あとで混乱する可能性があります。
なのでコントローラーで更新するには

ruby

1def create 2 # receiver がこれで合っているかは不明 3 # たぶん params で受け取らないといけない 4 receiver = User.where.not(id:current_user.id).order(:received_at).first 5 @post = Post.new(post_params) 6 @post.sender_id = current_user.id 7 @post.receiver_id = receiver.id 8 @post.save! 9 10 receiver.update(received_at: Time.current) 11 12 redirect_to posts_path 13end

投稿2021/02/18 05:44

neko_daisuki

総合スコア2090

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

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

sasaharukimedes

2021/02/22 00:35

@neko_daisukiさん 丁寧な回答ありがとうございます, 返答が遅れて申し訳ありません. 少しコードを見させてもらって, わからないことがあったらまた質問させていただいてよろしいでしょうか?
sasaharukimedes

2021/02/25 05:36

@neko_daisukiさん 遅くなってしまい申し訳ありません.いくつか質問したいのですが, 1, receiverカラムは, User テーブル内に作ったほうがいいでしょうか? (僕の場合は, 便宜上receiver_idをpost モデル, received_atをuserモデルに持たせていました ) 2, def createからに関してなのですが, receiver.update( received_at: Time.current)のところで, 手紙を受け取った時点の時刻がreceived_atになるようになっていますでしょうか?
neko_daisuki

2021/02/25 05:40

1 は receiver_idをpost モデル, received_atをuserモデルで問題ないと思います。 2 は「手紙を受け取った時点」が「Postが作成されたとき」ならそうなっています。
sasaharukimedes

2021/02/26 02:38

@neko_daisukiさん ありがとうございます. 1に関してですが, 僕の設計で問題ないということなら, "receiver = User.where.not(id:current_user.id).order(:received_at).first" この部分に関しては, userテーブルに新しくreceiver カラムを追加するということでしょうか? 一応, user modelのschema.rbも追加しておくので見てみてくれると嬉しいです. 2, 一応そのつもりです. ポストの送信先が "received_at"の値が一番古い人のIDになってくれればいいので. そして, 受け取った人のreceived_atは, ポストを受け取った時刻になっていればいいので.
sasaharukimedes

2021/02/26 05:44

上の質問に加えてですが, コントローラの回答 (def create からのもの) と, modelに書き込む方は, どちらもやらなければいけないものではなくどちらか一方だけで良いものですよね?
neko_daisuki

2021/02/26 06:22

receiver = User.where.not(id:current_user.id).order(:received_at).first で何を取得したいのかいまいち分かりませんが、これで発行されるクエリにUserのreceiverカラムは必要ありません。 received_atは必要です。 どちらか一方で更新されます。
sasaharukimedes

2021/02/26 06:34

@neko_daisukiさん ようやく理解できました!自分の理解不足に何度もお付き合いいただきありがとうございます!ベストアンサーにさせてもらいます!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.36%

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

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

質問する

関連した質問