プログラミング勉強中!!

TECH::EXPERT 40期 受講生の筆者がその日学んだことをアウトプットしていくブログです。学習量によっては全て書ききれないこともあります。お気付きのことありましたバシバシコメントください!!

ransackによる検索機能の実装

はい、こんばんは。

今回はransackというgemを用いて、検索機能を実装してみようと思います。

ransackのインストール

Gemfile

gem 'ransack'

ターミナル

アプリ名$ bundle install

名称による検索

今回はトップページのindexアクションに検索機能をつけたいので、下記のように記載します。

app/controller/tasks_controller.rb

def index
 @q = current_user.tasks.ransack(params[:q])
 @tasks = @q.result(distinct: true).recent
end

※この@qは公式ドキュメントに指定してあります。詳しくは下記のREADMENIあります。

github.com

検索フォームの実装

ransackを導入すると、search_form_forというメソッドが使えるようになります。

これは、form_forに変わるヘルパーとして使えますので、form_forの頭にsearch_をつけてください。

ここでは、indexアクションに対して検索フォームを実装して行きます。

名称による検索
qpp/tasks/views/index.html.slim

= search_form_for @q, class: 'hogehoge'
 .form-search
  = f.label :name_cont, '名称', class: 'hogehoge'
  .form-search__name
   =f.search_fireld :name_cont, class: 'hogehoge'
 .form-group
 = f.submit class: 'hogehoge'
登録日時による検索

名称による検索に以下の部分を追加します。

qpp/tasks/views/index.html.slim

= search_form_for @q, class: 'hogehoge'
 .form-search
  = f.label :name_cont, '名称', class: 'hogehoge'
  .form-search__name
   =f.search_fireld :name_cont, class: 'hogehoge'
#登録日時による検索
 .form-search
  = f.label :created_at_gteq, '登録日時', class: 'hogehoge'
  .form-search__date
   = f.search_field :created_at_gteq, class: 'hogehoge'
#追加完了。indexに検索フォームを追加
 .form-group
 = f.submit class: 'hogehoge'

検索マッチャー

上記で気になるのが、:namecontと:created_at_gteqではないでしょうか。

これはransackが用意している検索マッチャーと言われるものです。

githubにも上がっていますが、一応意味を説明すると、contでは検索のワードを含むという意味になります。gteqに関してはgreater than or equalと解説があります。

これは、「項目がフォームに入力した値と同じか、それより大きい」を条件として検索してくれます。

ソート機能の実装

変更前

app/views/tasks/index.html.task

・・・・
・・・・

tr
      th = Task.human_attribute_name(:name)
      th = Task.human_attribute_name(:created_at)
th
  tbody
    - @tasks.each do |task|
      tr
        td = link_to task.name,task
        td = task.created_at
        td
          = link_to '編集', edit_task_path(task), class: 'hogehoge'
          = link_to '削除', task, method: :delete, data: { confirm:"タスク「task.name」を削除します。よろしいですか?" }, class: 'hogehoge'

これをransakckのヘルパーsort_linkを使って記述を変更します。

sort_linkとは、ソート部分ができる見出しをつ食うことができるヘルパーです。

変更後

app/views/tasks/index.html.slim


tr
      th = sort_link(@q, :name)
      th = Task.human_attribute_name(:created_at)
th
  tbody
    - @tasks.each do |task|
      tr
        td = link_to task.name,task
        td = task.created_at
        td
          = link_to '編集', edit_task_path(task), class: 'btn btn-primary mr-3'
          = link_to '削除', task, method: :delete, data: { confirm:"タスク「task.name」を削除します。よろしいですか?" }, class: 'btn btn-danger'

上記のようにth = の部分を変更するだけでソート機能が実装できます。

検索機能は複雑化と思いきや、案外簡単に実装できました。

皆様もお試しください。

それでは。

転職 面接

はい、こんばんは。

久しぶりの投稿となってしまいましたが、今回は何社か面接に行って参りましたので、感想を投稿したいと思います。

カジュアル面接

カジュアル面接とは

ガチガチの面接ではなく、求職者と人事担当者が気軽に話をする機会を作るための面接です。IT業界では主流の形式となってきます。まずカジュアル面接、ついで本番の面接という流れです。

求職者としても、企業の雰囲気が知れる、という意味で非常に有意義な面談でした。

また、事前のやりとりには含まれていないが、履歴書の提出を要求されることもあるので、履歴書、職務経歴書の準備はしっかりとしよう。(備忘録)

何を話すの?

主に、転職理由、その会社の志望動機、なぜエンジニアを目指したのか?会社に入ったらどうなりたいの?今注目している技術は?など、様々あります。

本日問としてあり、困惑してしまったのが、会社に入ったらどうなりたいの?という質問と、今注目している技術は?という質問に対してでした。

個人的に思っていることはあったのですが、うまく言葉にするには普段から言葉にしているかどうかが分かれ目だと思います。

また、最新の技術に関しては、VRとしか答えられなかった自分が恥ずかしい思いであります。

移動時間を活用して、情報を仕入れて行きたいと思います。

活用するアプリとしては

NEWSPICKS

TechCrunch

などを考えています。

他、何かよいアプリがあれば、教えていただけますと大変助かります。

ということで、今日は面接に行った話をかる〜く書かせていただきました。

ご対応いただいた採用ご担当社様には感謝しかありません。

もっと自分を磨いて出直します!!

それでは。

共通の処理をまとめる(コントローラー編)

はい、こんばんは。

コントローラでの共通の処理のまとめ方をアウトプットします!!

Tasks_controller.rb

def show
 @task = current_user.tasks.find(params[:id])
end

def edit
 @task.update!(task_params)
end

def update
 @task = current_user.tasks.find(params[:id])
 @task.update!(task_params)
end

def destroy
 @task.update!(task_params)
 @task.destroy
end
 
private

def task_params
  params.require(:task).permit(:name, :description)
end

こんな記述があったとします。

共通している処理は

@task = current_user.tasks.find(params[:id])

ですね。

これはRails の DRYの原則(全ての記述は単一且つ明確でなければならない)に基づき、まとめてやる必要があります。

手順は以下の通りです。

①共通の処理をまとめてprivate以下に定義する。

Tasks_controller.rb

private

def task_params
 params.require(:task).permit(:name, :description)
end

def set_task
 @task = current_user.tasks.find(params[:id])  #共通の処理をまとめた。
end

②before_actionを利用して、set_taskメソッドを各アクションの実行前に呼び出す

Tasks_controller.rb

class TasksController < ApplicationController
before_action :set_task, only: [:show, :edit, :update, :destroy] 
#only: []に対して:set_taskを適用するということ
・
・
・
end

③各アクションで定義していた共通の処理を消す

Tasks_controller.rb

class TasksController < ApplicationController
before_action :set_task, only: [:show, :edit, :update, :destroy] 
#only: []に対して:set_taskを適用するということ

def show
end

def edit
 @task.update!(task_params)
end

def update
 @task.update!(task_params)
end

def destroy
 @task.update!(task_params)
 @task.destroy
end
 
private

def task_params
  params.require(:task).permit(:name, :description)
end

def set_task
 @task = current_user.tasks.find(params[:id])  #共通の処理をまとめた。
end

これで共通の処理をまとめることができました。

実際にアプリを動かしてみると、うまくいくはずです。

それでは。

LoadErrorでrails cが使えない方へ

はい、こんばんは。

Rails 5.2.1でアプリを作成しているのですが、その際 rails cが起動しなくなりました。

無事エラーは解決したので、共有させていただきたく思います。

アプリ名 $ rails c

上記のようにしたところ、下記のエラーが出ました。

dlopen(/Users/yohei/.rbenv/versions/2.5.1/lib/ruby/2.5.0/x86_64-darwin17/readline.bundle, 9): Library not loaded: /usr/local/opt/readline/lib/libreadline.7.dylib (LoadError)

原因はreadlineのgemがインストールされていないことでした。

Gemfile

gem 'rb-readline'  #readline のgemをインストール

で 

bundle install

すると、無事rails cが起動できました。

参考にさせていただいた記事。

qiita.com

取り急ぎ共有のみ。

それでは。

ユーザ管理機能の作り方 (admin)

はい、こんにちは

現在作成中のアプリに管理者権限を追加いたしましたので、アウトプットいたします。

ユーザ管理機能とは

アプリのユーザーを登録したり、削除したりなんでもできる権限を与えること

手順

①userモデルに、adminフラグを追加する。

まず、ユーザが管理者かどうかを表すフラグを追加します。

ターミナル/アプリ名$ bin/rails g migration add_column_to_users

実行結果 f:id:g1034725:20190118155927p:plain

作成されたマイグレーションファイルを下記のように変更する。

db/migrate/xxxx_add_column_to_users

def change
  add_column :users, :admin, boolean, default: false, null: false
end

保存後にマイグレートする。

ターミナル/アプリ名$ bin/rails db:migrate

f:id:g1034725:20190118160613p:plain

ユーザ管理のためのコントローラを実装する

ターミナル/アプリ名$ bin/rails g controller Admin::Users index new show edit

Admin::とつけることで、/app/controller/admin/users_controllerと自動的にadmin/users_controllerのように階層化してくれる。

また、Admin::Usersの後にindex new show editとすることで、routingも自動生成してくれる。(viewファイルも)

f:id:g1034725:20190118161420p:plain

routingを修正する。

get 'index#users'と言う形式になっているので、resourcesに変更する。

namespace :admin do
    resources :users   #ここのみ変更する。
  end

コントローラの記述

app/controller/admin/users_controller.rb

def index
    @users = User.all
  end

  def new
    @user = User.new
  end

def create
    @user = Use.new(user_params)

    if user.save
        redirect_to admin_users_path, notice: "ユーザー「#{@user.name}」を登録しました"
    else
        render :new
    end
  end

上記のような感じで記述していく。

ビューの記述

比較してみてみる。

通常のユーザの記述(@taskを作成)

app/views/tasks/new.html.slim

= form_with model: @task, local: true do |f|
  .form-group
    = f.label :name
    = f.text_field :name,

adminユーザの記述(adminユーザを作成)

app/views/admin/users

= form_with model: [:admin, @user], local: true do |f|
    .form-group
      = f.label :name, '名前'
      = f.text_field :name

modelの指定の仕方に違いがあります。adminでのユーザ作成なので[:admin, @user]と言う指定の仕方をしていますね。

もしチャレンジされる方はここら辺の記述に気をつけていただければと思います。

もし何かありましたらコメントお願いいたします!!

それでは。

モデルの検証(バリデーション)について

はい、こんばんは。

本日は検証(Validation)についてアウトプットします。

バリデーションとは

データの内容が正しいかどうかを検証する仕組みのことです。 仕組みとしては、レコードをデータベースに登録・更新などする前に検証し、もしエラーがあれば登録・更新などをせずに差し戻すという仕組みになっています。

以下、具体的なコードをみてみましょう。

バリデーションのコード

tasks_controller.rb

  def new
    @task = Task.new
  end

   def create
    @task = Task.new(task_params)

    if @task.save
     redirect_to tasks_url, notice: "タスク「#{@task.name}」を登録しました"
        else
         render :new
    end
  end

まず、tasks_controllerのnewアクションからフォームがcreateアクションに送られます。createアクションに行ったデータは if @task.save・・・で登録されようとするのですが、ここでデータが正しく入力されているのか検証します。その記述はモデルにすることになります。

app/models/tasks.rb

  class Task < ApplicationRecord
 #バリデーションの記述
    validates :name, presence: true                    #データは入力されているか?
 validates :name, length: { maximum: 30 }    #30字以内であるか?
  end

以上でバリデーションの記述は終わりです。

これで空欄にした場合と30字を超えた場合はデータがsaveされずに差し戻されることとなります。

ここで疑問に思ったのが、 :nameってなんだ?ということでした。

答えは下記でした。

app/views/new.html.slim

= form_with model: @task, local: true do |f|
  .form-group
    = f.label :name
    = f.text_field :name, class: 'form-control', id: 'task_name'

上記のように、form_withのコードの中にf.label :nameとあります。ここの属性を指定していたのでした。

それでは。

sublime textでslimをシンタックスハイライトする方法

はい、こんにちは。

本日の学びを早速アウトプットしていきます。

sublime textでslimをシンタックスハイライトする方法です。

slimとは・・・Rubyのテンプレートエンジンのこと。erb、Hamlの仲間と考えると理解しやすいと思われます。

とにかく記述がシンプルなのが特徴である。

erbとHamlを使ってきたが、slimを使って見ようと決意しました。

sublime text でシンタックスハイライトするには以下の通りです。

sublime textを開く

sublime text上でcommand + shift + p

すると、入力画面が出てくるので、Package controll: install Package と入力

Ruby Slim

と入力してsublime textを再起動する。