rails 独学して軽くにちゃんまとめつくる

マイクロポストの作成

$ rails generate model Micropost content:text user:references

 

インデックスをいれる

class CreateMicroposts < ActiveRecord::Migration[5.0]
  def change
    create_table :microposts do |t|
      t.text :content
      t.references :user, foreign_key: true

      t.timestamps
    end
    add_index :microposts, [:user_id, :created_at]
  end
end

バリデーション

belongs_to :user
validates
:user_id, presence: true
validates :content, presence: true, length: { maximum: 140 }
default_scope -> { order(created_at: :desc) }
 

has_many と belongs_to

belongs_toは自動的に書かれている。

app/models/user.rb

  has_many :microposts, dependent: :destroy

 

 

偽投稿の作成

 

users = User.order(:created_at).take(6)

50.times do
  content = Faker::Lorem.sentence(5)
  users.each {|user| user.microposts.create!(content: content) }
end

 いったんリセット

$ rails db:migrate:reset
$ rails db:seed

 

----------------------------------------------------

 

ルーティング

resources :microposts,  only: [:create, :destroy]

 

 

パーシャル

 <li id="micropost-<%= micropost.id %>">
  <%= link_to gravatar_for(micropost.user, size: 50), micropost.user %>
  <span class="user"><%= link_to micropost.user.name, micropost.user %></span>
  <span class="content"><%= micropost.content %></span>
  <span class="timestamp">
    Posted <%= time_ago_in_words(micropost.created_at) %>
  </span>
</li>

 

 

ここではマイクロポストの独立した index ビューは作成せずに,ユーザーの show ページの隣におじゃまさせていただくことにする.とはいえ書くことは index と同じ.render でパーシャルを持ってくるのと,will_pagenate でページネーションを作成する.

 

def show
    @user = User.find(params[:id])
    @microposts = @user.microposts.paginate(page: params[:page])
end

 

showビュー

まあなんの特徴もない,indexのページ.render で一覧のパーシャルを呼び出し,will_paginateでページネーション.ただ, if user.microposts.any? というのに注意.

 

app/views/users/show.html.erb

<% provide(:title, @user.name) %>
<div class="row">
  <aside class="col-md-4">
    <section class="user_info">
      <h1>
        <%= gravatar_for @user %>
        <%= @user.name %>
      </h1>
    </section>
  </aside>
  <div class="col-md-8">
    <% if @user.microposts.any? %>
      <h3>Microposts (<%= @user.microposts.count %>)</h3>
      <ol class="microposts">
        <%= render @microposts %>
      </ol>
      <%= will_paginate @microposts %>
  </div>
</div>

 

ログインの要請

Userコントローラーで logged_in_user メソッドでログインしてるかどうかをたしかめた.マイクロポストコントローラーでもログインしてるかどうかを確かめたい.だからapplication_controller.rbにリファクタリングする.

application_controller.rb

private
def logged_in_user
    unless logged_in?
      store_location
      flash[:danger] = "Please log in"
      redirect_to login_url
    end
  end

 コントローラー

before_action でログインしていることを要請した.

class MicropostsController < ApplicationController
  before_action :logged_in_user, only: [:create, :destroy]
 
  def create
  end
 
  def destroy
  end
end

 

 

マイクロポストの作成.createアクションでいじることがある.とはいってもこれも定石通りに事をすすめていけばいいから心配することはない.

create はまずマイクロポストを呼び出して,セーブできか否かで判断.メッセージと移動先を忘れずに.

さらに micropost_params メソッドを作成し,ストロングパラメーラーで制御する.

 

  def create
    @micropost = current_user.microposts.build(micropost_params)
    if @micropost.save
      flash[:success] = "マイクロポストはセーブされました"
      redirect_to root_url
    else
      render 'static_pages/home'
    end
  end



  private
    def micropost_params
      params.require(:micropost).permit(:content)
    end

 

 

 

app/views/static_pages/home.html.erb

<% if logged_in? %>
  <div class="row">
    <aside class="col-md-4">
      <section class="user_info">
        <%= render 'shared/user_info' %>
      </section>
      <section class="micropost_form">
        <%= render 'shared/micropost_form' %>
      </section>
    </aside>
  </div>
<% else %>
<div class="center jumbotron">
    <h1>Welcome to the Sample App</h1>
    <h2>



<% end %>

 

 

 

 

app/views/shared/_user_info.html.erb

<%= link_to gravatar_for(current_user, size: 50), current_user %>
<h1><%= current_user.name %></h1>
<span><%= link_to "view my profile", current_user %></span>
<span><%= pluralize(current_user.microposts.count, "micropost") %></span>

 

app/views/shared/_micropost_form.html.erb

<%= form_for(@micropost) do |f| %>
  <%= render 'shared/error_messages', object: f.object %>
  <div class="field">
    <%= f.text_area :content, placeholder: "Compose new micropost..." %>
  </div>
  <%= f.submit "Post", class: "btn btn-primary" %>
<% end %>

 

 

 

static_pages.html.erb

  def home
    @micropost = current_user.microposts.build if logged_in?
  end

 ----------------------------------------------------

フィードの原型

 

app/models/user.rb

  def feed
    Micropost.where("user_id = ?", id)
  end

 

  
def home if logged_in? @micropost = current_user.microposts.build @feed_items = current_user.feed.paginate(page: params[:page]) end end

 

 app/views/shared/_feed.html.erb

<% if @feed_items.any? %>
  <ol class="microposts">
    <%= render @feed_items %>
  </ol>
  <%= will_paginate @feed_items %>
<% end %>

 

<aside> の下にかく。

app/views/static_pages/home.html.erb

    <div class="col-md-8">
      <h3>Micropost Feed</h3>
      <%= render 'shared/feed' %>
    </div>

 

 

app/controllers/microposts_controller.rb

 def create
    @micropost = current_user.microposts.build(micropost_params)
    if @micropost.save
      flash[:success] = "Micropost created!"
      redirect_to root_url
    else
      @feed_items = []
      render 'static_pages/home'
    end
  end