Railsチュートリアルで躓くところまとめ(7章~8章)

スポンサーリンク

ユーザーの表示

undefined method for nil:NilClass
このエラーがでたときは大体インスタンスが空、もしくは、存在しないurlを参照している可能性が高い。たとえばid1のユーザーがいないのに1のurlにアクセスしているなど。

update_attributes()
update_attributesはテーブルの上書きができるみたい。

user.update_attributes(name: "Example", email: "example@railstutorial.org", password: "foobar")
スポンサーリンク

新規登録フォーム

form_forヘルパー
form_forの場合は引数にモデルを指定する。(よくわからないけどインスタンス変数でも可。フォームの送信先にidを指定するときなど)またオプションでurlを指定することによって、フォームの送信先を指定。ブロック変数|f|を使用することにより、入力フォームを簡単に作成することができる。

<% provide(:title, 'Sign up') %>
<h1>Sign up</h1>

<div class="row">
  <div class="col-md-6 col-md-offset-3">
    <% @user.errors.full_messages.each do |message|%>
    <%= message%>
    <%end%>
    <%= form_for(@user, url: signup_path) do |f| %>

      <%= f.label :name %>
      <%= f.text_field :name, class: 'form-control' %>

      <%= f.label :email %>
      <%= f.email_field :email, class: 'form-control' %>

      <%= f.label :password %>
      <%= f.password_field :password, class: 'form-control' %>

      <%= f.submit "Create my account", class: "btn btn-primary" %>
    <% end %>
  </div>
</div>

このページにアクセスしてページのソースを表示で確認すればどういう構造になっているかわかる

createアクション

  def create
    @user = User.new(user_params)

    if @user.save
      flash[:notice] = "登録しました"
      redirect_to(@user)
    else
      render 'new'
    end
  end

  private

  def user_params
    params.require(:user).permit(:name, :email, :password)
  end

form_forを使ったらデータの受け取りはがいろいろややこしい。params.require(:user).permitうんぬんはこういうもんだと思うしかない。あとredirect_to()の引数に@userを指定するとなぜか自動でユーザーの詳細ページにとんでくれる。

session ログイン機能の実装

railsチュートリアルでは8章にでてくる。ログインフォームは下記のようなものになっている

ログインフォームの作成

  <div class="col-md-6 col-md-offset-3">
    <%= form_for(:session, url: login_path) do |f| %>

      <%= f.label :email %>
      <%= f.email_field :email, class: 'form-control' %>

      <%= f.label :password %>
      <%= f.password_field :password, class: 'form-control' %>

      <%= f.submit "Log in", class: "btn btn-primary" %>
    <% end %>

    <p>New user? <%= link_to "Sign up now!", signup_path %></p>
  </div>

form_forの引数が:sessionとなっていてこれはなんなんだと思いがちだが、ここの文字自体はなんでもよいっぽい。url: login_pathはpostに送信するようになっている(createアクション)

createアクションの実装
railsチュートリアルではちょっとしたことでヘルパーを定義したりといろいろとうざい。もうこれでいいやって感じ。@user.autheticateはpasswordがただしければtrue。なぜかelseになっているのにerrors.full_messagesが使えないので@userをelse定義。

  def create
    @user = User.find_by(email: params[:session][:email].downcase)
    if @user && @user.authenticate(params[:session][:password])
      session[:user_id] = @user.id
      redirect_to(@user)
    else
      flash[:notice] = "ログインに失敗しました"
      @user = User.new
      render 'new'
    end
  end

現在のユーザー
ここでもヘルパーを作らせようとしてくるのでうざい。あと||=とかよくわらかないのがでてくるのもうざい。

めんどくさいのでbefore_actionで定義

class ApplicationController < ActionController::Base
before_action :set_current_user
def set_current_user
  @current_user = User.find_by(id: session[:user_id])
end
end

これで動くからべつにいいだろたぶん。

ログイン・ログアウト状態でリンクをわける

<header class="navbar navbar-fixed-top navbar-inverse">
  <div class="container">
    <%= link_to "sample app", root_path, id: "logo" %>
    <nav>
      <ul class="nav navbar-nav navbar-right">
        <li><%= link_to "Home", root_path %></li>
        <%if  @current_user %>
          <li><%= link_to "Users", '#' %></li>
          <li class="dropdown">
            <a href="#" class="dropdown-toggle" data-toggle="dropdown">
              Account <b class="caret"></b>
            </a>
            <ul class="dropdown-menu">
              <li><%= link_to "Profile", user_path(@current_user) %></li>
              <li><%= link_to "Settings", '#' %></li>
              <li class="divider"></li>
              <li>
                <%= link_to "Log out", logout_path, method: :delete %>
              </li>
            </ul>
          </li>
        <% else %>
          <li><%= link_to "Log in", login_path %></li>
        <% end %>
      </ul>
    </nav>
  </div>
</header>

ヘルパーを作る作業がだるすぎたので、条件分岐で@current_userを使っている。set_current_userメソッドで@current_userを定義している。これは動くからいいだろたぶん。

jqueryのドロップダウンメニュー
jquery_rails
チュートリアルでjqueryを使えばドロップダウンメニューが動くとかいてあるのに動かない。なぜか調べていたら、gemが入ってない。gemを入れても動かない。gemをいれたあとは一旦サーバーを切ってもう一回たちあげる必要がある。だるい。

同じような事例があったようなのではっとくRuby on Rails – 5.1.0でjQueryが使いたい|teratail

新規登録時にログインさせる
チュートリアルではごちゃごちゃやっているけど新規登録のアクションに session[:user_id] = @user.idを追加すればいいだけ

  def create
    @user = User.new(user_params)

    if @user.save
      session[:user_id] = @user.id
      flash[:notice] = "登録しました"
      redirect_to(@user)
    else
      render 'new'
    end
  end

ログアウト
railsチュートリアルではここでもよくわからないことをさせようとしてくれる。

def destroy
  session[:user_id] = nil
  redirect_to(root_path)
end

ログアウトするならsession[:user_id] = nilとすればいいだけ。動くからいいだろたぶん

コメント

タイトルとURLをコピーしました