ユーザーの表示
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を使えばドロップダウンメニューが動くとかいてあるのに動かない。なぜか調べていたら、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とすればいいだけ。動くからいいだろたぶん
コメント