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

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

ただいまの
回答率

88.91%

has_many belongs_toを使って User と Postを関連付けさせたい。

解決済

回答 1

投稿 編集

  • 評価
  • クリップ 1
  • VIEW 179

atage517

score 36

やりたいこと

Ruby on Rails の has_many と belongs_toを使い Userのsubject要素だけをpostsで表示したい。

わからないこと

今学生版のtwitterのようなアプリを作っており、自分とおなじ学部(subject)の人だけのpostsに表示したいのですが。has_many と belongs_toを使ってもうまく表示できません。

class PostsController < ApplicationController  

  def index
    @posts = Post.all.order(created_at: :desc)
    @posts = Post.search(params[:search])
  end

  def index_updated_at
    @posts = Post.all.order(updated_at: :desc)
 end

  def index_relative

  end


Userの投稿をTeratailのように 作成順(index) 更新順(index_updated_at) 関連順(index_relative)
関連順のindexでは自分とおなじ学部(subejct)の人の投稿だけを表示するのようにしたいです。

作成順 更新順は上記のコードのようにできましたが、関連順は Post model と User model の関連性を示さなければいけないですがそれのやり方がわかりません。

class Post < ApplicationRecord

  belongs_to :holder, class_name: 'User', foreign_key: 'user_id'
class User < ApplicationRecord
has_many :posts, dependent: :destroy


上記は has_many belongs_to の関係性のmodelです。

<div class="main posts-index">

  <div class="container">
    <div class="posts-search">
      <ul>
        <li><%= link_to("/posts/index") do %>
        <i class="fas fa-indent"> 作成順</i>
        <% end %>
      </li>
      <li>
      <%= link_to("/posts/index/updated_at") do %>
      <i class="fas fa-indent"> 更新順</i>
      <% end %></li>
      <li>
      <%= link_to("/posts/index/relative") do %>
      <i class="fas fa-indent"> 関連順</i>
      <% end %></li>
      </ul>
    </div>
    <br>
    <br>
    <% @posts.each do |post| %>
      <div class="posts-index-item">
        <% if Star.find_by(post_id: post.id)%>
        <i class="fas fa-certificate"></i>
        <% end %>
        <%= link_to image_tag("/user_images/#{post.user.image_name}"), "/users/#{post.user.id}"%>
        <%= link_to(post.user.name, "/users/#{post.user.id}", {class: "text-weight"})%>
        <%= link_to(post.user.uni, "/#{post.user.uni}/index", {class: "text-weight"})%>
        <%= link_to(post.user.subject, "/#{post.user.uni}/#{post.user.subject}/index ", {class: "text-weight"})%>
        <p class="post-created_at"><%= time_ago_in_words post.created_at%></p>
        <br>
        <%= link_to(post.title.truncate(50), "/posts/#{post.id}", {class: "text-weight"})%>
        <br>
        <%= link_to(post.content.truncate(80, omission: '...もっと見る'), "/posts/#{post.id}") %>
      </div>
    <% end %>
  </div>
</div>

上記はindex_relative.html.erbのviewです。

class CreateUsers < ActiveRecord::Migration[6.0]
  def change
    create_table :users do |t|
      t.string :name
      t.string :email
      t.text :uni
      t.text :subject
      t.string :image_name
      t.string :password

      t.timestamps
    end
  end
end
class CreatePosts < ActiveRecord::Migration[6.0]
  def change
    create_table :posts do |t|
      t.text :title
      t.text :content
      t.integer :user_id

      t.timestamps
    end
  end
end


上記はUserとPostのmigrationファイルのなかみです
どのようにしたらpostをuserモデルの関係性を示し、自分をおなじ学部(subject)のユーザーの投稿のみを表示できるようになるでしょうか?

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

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

checkベストアンサー

+1

PostにUserのテーブルをくっつけて(joinして)Userのsubjectで検索するのはどうでしょう?

@posts = Post.joins(:holder).where('user.subject' => @current_user.subject)


@current_userはログインしているUserのインスタンスを想定しています。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2020/07/15 16:02

    satoshihさんありがとうございます!
    SQLite3::SQLException: no such column: user.subject

    satoshihさんのコードを入力したらこのエラーコードが出ました。

    PostのModelには以下のような戻り値を指定しているんですが何かうまい方法はないですかね?

    def user
    return User.find_by(id: self.user_id)
    end

    やろうとしていることはPostのUser_idと繋がっているUserのSubjectを表示するということなのでそこまで複雑なコードは必要ないきもするんですけどね

    キャンセル

  • 2020/07/15 16:48

    > SQLite3::SQLException: no such column: user.subject
    失礼タイポしてますね。
    'user.subject' => 'users.subject'
    にしたら動かないですか?

    > def user
    > return User.find_by(id: self.user_id)
    > end
    これはそのまま belongs_to :user のことでは?

    キャンセル

  • 2020/07/15 18:09

    無事できました!!
    本当にありがとううございます!joinsなんて技があるとは知りませんでした!これからも学習に励みます!

    キャンセル

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

  • ただいまの回答率 88.91%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る