0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Railsでattr_accsessor使ってますか?

Last updated at Posted at 2021-04-04

はじめに

Rubyを勉強し始めたときに必ず出てくる attr_accsessor
しかしRailsを勉強し始めて、ポートフォリオ等を作る過程では、中々触れる機会が減ると思います。

この記事で触れない部分

  • attr_accsessorの細かい説明
  • rubyの基礎基礎的な部分
  • railsの基礎的な部分

attr_accsessorが有効活用できる場面

  • Userモデル
id name
1 ユーザーA
2 ユーザーB

以下のような要件を想定

Userモデルの中に、ユーザーの名前情報を格納するnameという属性が定義されている
しかしユーザー情報の登録・編集フォームでは、名字と名前を別々のテキストフィールドから入力させたい。

上記のユースケースの場合、attr_accsessorが活躍する場面です。
nameカラム塗とは別に、今回は fisrt_namelast_nameという擬似的なフィールドを定義してあげましょう。

実装

モデル

以下を定義したことで、Userモデルのインスタンスを作成すると、fisrt_namelast_nameのゲッターとセッターが使えるようになりました。

app/models/user.rb

class User < ApplicationRecord
  attr_accsessor :fisrt_name, :last_name
end

ビューとコントローラ側でも fisrt_namelast_nameが使えるようにしましょう。

コントローラ

app/controllers/users_controller
class UsersController < ApplicationController
  
  def new
    @user = User.new
  end
  
  def create
    user = User.new(user_params)
    user.save
  end

  private

    def user_params
      params.require(:user).permit(:first_name, :last_name)
    end
end

コントローラ側ではstrong parameterに設定してあげます。

ビュー

app/views/users/new.html.erb
  <%= form_with model: @user, local: true, url: url, method: method do |f| %>
    <!-- 姓 -->
    <%= f.label :last_name %>
    <%= f.text_field :last_name %>

    <!-- 名 -->
    <%= f.label :first_name %>
    <%= f.text_field :first_name %>
    
    <%= f.submit "送信" %>
  <% end %>

ビューではそのままtext_feildのname属性にlast_name first_name を指定します

ここまでで下準備は出来ました。
ただ現状では、last_namefirst_nameのパラメータをフォームから送信する事は出来ても、受け取り側が不十分です。
具体的には、実際にDBに登録されるのは nameという属性です。
last_namefirst_nameはDBとモデルには定義されていないので登録時にはそのまま使う事が出来ません。

そこでモデル側に、コントローラ側で受け取ったlast_namefirst_namenameに結合してあげる処理を実装します。

app/models/user.rb
class User < ApplicationRecord
  attr_accsessor :fisrt_name, :last_name

  # 以下追加分 

  # 登録処理の前に呼び出す
  before_save :create_fullname
  
  
  # last_name と first_nameの結合処理
  def create_fullname
    self.name = self.last_name.concat(" ",self.first_name)
  end
end

コールバックで、user.saveの直前に create_fullnameを呼び出します。

ちなみに concat(" ",self.first_name)で半角スペースを入れているのは、編集時のデリミタを指定できるようにするためです。
そのまま結合をしてしまうと、name編集時にどこで文字列を分割するかが分からなくなるからです。

まとめ

attr_accsessorを使うユースケースよりの記事になってしまいましたが、やhりRubyの基礎を理解しておくことでアプリケーションの要件が複雑化した際の対応力が圧倒的に変わります。
Railsは便利なフレームワーク故に、ついRubyの基礎を忘れてしまいがちです。
自分も今一度基礎を見直して日々精進します

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?