Mainichi Engineering

H29年の新卒Railsエンジニアが日々学んだことを徒然に書きます。

modelに存在しないカラムを仮想的に存在させた状態にする

Railsで登録フォームなどを作っている時に「ここの入力フォームを2つに分割して書かせるようにしたい」という場面がありました。
僕みたいな初心者railsエンジニアは、「DBの設計から変更しなきゃ….」と考えてしまうのですが、先輩に聞くと vartial attributes という方法を使えば簡単に実装できるというので、実際に使ってみました。

vartual attributes(仮想属性)とは

vartual attributesとは、読んで字のごとく仮想的な属性のことです。
これを用いることで、上に書いたようにデータベースを変更しないで、登録・編集フォームを変更することができます。

今回の使用状況

郵便番号の登録フォームを上3桁、下4桁の分割したフォームに変更させる。
例)123-4567の様に"-“をフォームに追加する。

手順

1. 郵便番号を上3桁、下3桁の属性に分ける

# /models/address.rb

#table: adresses
#column
#string: address

class Address < ApplicationRecord
  attr_writer :first_address, :last_address

  validates :address, format: { with: /\A\d{7}\z/ }
  validates :first_address, presence: true
  validates :last_address, presence: true

  #先にset_addressを呼ばないとバリデーションエラーになる
  before_validation :set_address

  def first_address
    @first_address || self.address[0..2] if self.address.present?
  end

  def last_address
    @last_address || self.address[3..6] if self.address.present?
  end

  #DBカラムはaddressのため、バリデーション前に結合して設定する
  def set_address
    self.address = [@first_address, @last_address].join
  end
end

ここでfirst_addressとlast_addressというVirtual Attributes(仮想属性)を追加しています。

注目箇所は、attr_writerというRubyモジュールです。
attr_writerメソッドは、クラスやモジュールにインスタンス変数を書き込むためのアクセサメソッドを定義します。 attr_writerメソッドを使うことで、書き込み用のaddressカラムを分けることができているということになります。

やってないけど、もしフォームで作成したaddressに"-“表示するためには、attr_accesorメソッドを使えばいいってことかな??  

あと

  def first_address
    @first_address || self.address[0..2] if self.address.present?
  end

この文では、住所に入る数値の制限も書かれているのがわかります。
これで、first_address、last_addressという、属性が追加されました。

2. view画面に郵便番号入力欄を追加する

次に郵便番号入力欄を2つに分けて入力できるようにします。

#views/addresses/_form.html.haml

= form_for @address do |f|
  - if @address.errors.any?
    #error_explanation
      %h2= "#{pluralize(@address.errors.count, "error")}"
      %ul
        - @address.errors.full_messages.each do |msg|
          %li= msg

  .field
    = f.label :address
    = f.text_field :first_address
    = f.text_field :last_address

  .actions
    = f.submit 'Save'

二つに分けた"“f.text_field”“を追加で書きます。

3. StrongPararametersにfirst_addressとlast_addressの入力を許可させる

最後にcontrollerのStrongPararametersにfirst_addressとlast_addressの入力を許可させます。

#controllers/addresses_controller.rb

private
    def address_params
      params.require(:address).permit(:first_address,
                                      :last_address)
    end
end

フォーム画面 f:id:mainichiaisatu:20170326225130p:plain

これで追加できるようになったかと。
とりあえずひと安心。。。

ブログ始めようかと

初めまして。

今年の4月からエンジニアとして大分で働きます。 はてブロ初めてで、、、というか、ブログ自体初で、何を書いていいのやらなのですが、自分のために(エンジニアとして成長するべく!)これからしっかりと書いていこうと思います。

自己紹介

今まで、大学生やってました。もはやニートみたいな生活をだらだらとやってきたわけで、今思うと、もっと有意義にすごせたよな〜なんて後悔も多々あります。 学生ニートな生活を送っていたわけですが、学校の研究に関しては、まぁまぁ熱心に取り組んでいたとおもいます。 また、その辺については後日書いていければいいかなーと思っているのでお楽しみに。。

何を書くの??

主に書く内容として考えているのは、プログラム技術(多分Rubyメイン)関係のことを書いていきます。 大学の研究ではpythonいじいじしてたのもあるので、たまにハード触りたい時python使った何かも載せれたらいいな〜なんて思っています。

日頃自分がプログラムを書いていく中で「ここ重要だなぁ〜」「また使う時の備忘録になりそうだなぁ〜」って ことをかいていこうと思います。

正直ここに書くような内容は、google先生で調べれば出るような内容で溢れるかと。。。その辺はご容赦くださいm( )m ここに書くのは、自分のプログラミングに対する知見を増やすためというのが大きいんです。

いずれは役に立つオープンソースを自分でもどしどし載せれるようになっていきたいと思っています!頑張ります!!

*もし間違った情報等があればコメントくれたら嬉しいです。できるだけそう言ったことは、無いよう心がけますが。。。