アラフォーがお金持ちになるためエンジニア目指すブログ

お金も根性も学歴もないアラフォーまきのがエンジニアになってお金持ち目指すよ!

【Railsメモ】DBからランダムにデーターを拾って表示する

どうも、アラフォーまきのです。
難しそうだと思ってたけど、案外簡単にうまくいったところがあったのでメモっちゃう!
(現時点ではうまく動いてるけれど、なんせまきののやることだから…もし穴があれば教えてやってください)

MODEL

User・・・ユーザーのデーターが入ったusersテーブルを持ってる。

Work・・・各ユーザーの制作物のデーターが入ったworksテーブルを持ってる。

紐付け

ユーザーは、たくさんの制作物を持つことができる。

ユーザー(User):制作物(Work)
       1:n

<Userモデル>
has_many :works

<Workモデル>
belongs_to :user

これで紐付け完了!
ランダムに拾うだけなら、紐付けについてめもする必要ないけれど、このあとリンクをつけてジャンプする作業がある。

この時紐付けが関わるので一応めもった。

見せ方

Users#showをマイページに見立てて、全ユーザーの制作物をランダムに紹介するという想定。

worksテーブルには、titleというカラムがあって、制作物のタイトルが格納されているから、このタイトルをばばっと一覧に出す感じ。

コード

【users_controller.rb】

def show
    @user = User.find(params[:id])
    @works_random = Work.all.order("RANDOM()").limit(3)
end

1:@user
あとでランダムに表示した制作物にリンクをつけて、その制作物詳細へジャンプするために使う。

users#showのURLの中に、user.idが含まれているので、paramsはそのURLのuser.idを拾ってくれて、そのidと同じプライマリキーを持つユーザー情報を、usersテーブルから拾って@userへ格納してくれる。

2:@works_random.all
全制作物を対象にしているので、【.all】で全制作物の全データーをまるっと拾って欲しいよと書いてある。

3:.order("RANDOM()").limit(3)
<2>で全部対象にしているけれど、.orderすることで、全データーからランダムに3つ選んで、それだけを@works_randomに格納してもらってる。
RANDOMの後ろの( )の存在がよくわからない。この後の侍塾で聞いてみる。

複数のデーターが入っているから、変数名は複数形が素敵。

【users/show.html.erb】

みんなの制作物をランダム表示
<% @works_random.each do |work_random| %>
    <ul>
      <li>
        <% work = Work.find_by(id: work_random.id)%>
        <%= link_to(work_random.title, user_work_path(@user,work)) %>
      </li>
    </ul>
<% end %>

1:@works_random
複数(3つ)のデータが入っているから、eachでぐるぐるして1個ずつwork_randomに入れる。
work_randomは1個のデーターがはいっているから、単数形にすると素敵。

2:work = Work・・・
次の行で、表示した制作物のリンクから制作物の詳細画面へジャンプするとき、worksテーブルのプライマリキーを指定するために必要だった。

普通こういうのはコントローラのアクション内で書くけれど、コントローラのアクション内は【@works_random】で複数のデーターが入ってる。

3つの制作物のデーターが入っているわけだから、「worksのプライマリキーがほしいな!」といっても「3つのうちどのworksのプライマリキーだよ」となってしまうから、エラーになっちゃう。

eachで1個ずつworkを書き出す時なら、どのworkか特定できているから、コントローラではなくビューで書いた。

3:link_to・・・
これでwork_random.titleにリンクを貼ってる。

4:work_random.title
eachでぐるぐるして、work_randomに1つの制作物のデータが入った状態だから、worksテーブルの中のttitleを表示してよっていってる。

5:user_work_path(@user,work)
リンクをクリックした時の飛び先を指定してる。
prefixを使っていて、コンソールでrails routesすると、

user_work GET /users/:user_id/work/:id(.:format) work#show

となってた。

まずはprefixの【user_work】に_pathをつける。
次にURI Patternの【 /users/:user_id/work/:id】から、user_id とwork/:id=work.id(workのプライマリキー)が必要だってわかる。
そこで引数に【@user.id】と【work.id】を書く必要が出てくる。

だけど、【.id】は省略してもRailsがちゃんとよきに計らってくれるから、単に@user,workと書いた。

ちなみに、@userは最初にコントローラで定義してる。
workはビューのeachの二行下に書いた。

これで、ページをリロードするたびランダムに3つ制作物(work)を見せてくれるページになった。

実際は何秒か毎に拾えるようにしたいかなー。