+3

Serialize and validate Serialize

Nếu bạn đã từng sử dụng các phương thức trong Model ActiveRecord, bạn có thể gặp vấn đề lưu trữ một đối tượng phức tạp (như một Hash hoặc một mảng) vào trong cơ sở dữ liệu, mà không cần phải tạo ra các mối quan hệ giữa chúng.

ActiveRecord Serialize chính là giải pháp đơn giản nhất để giải quyết vấn đề đó

Một ví dụ điển hình có thể lưu trữ các sở thích của người dùng trong một hash:

Db

class CreateTimesheetSettings < ActiveRecord::Migration[5.0]
  def change
    create_table :timesheet_settings do |t|
      ...
      t.string :optional_settings

      ...
    end
  end
end

Model

class TimesheetSetting < ApplicationRecord
  serialize :optional_settings, Hash

  validates :optional_settings, presence: true
end

View

...
  <%= f.fields_for :optional_settings do |optional_setting| %>
      <%= optional_setting.label :time_in  %>
      <%= optional_setting.text_field :time_in %>
      <%= optional_setting.label :time_out  %>
      <%= optional_setting.text_field :time_out %>
      ...
  <% end %>
...

Sau khi submit form, optional_settings sẽ có giá trị như sau :

optional_settings = {"time_in"=>"Giờ vào", "time_out"=>"Giờ ra", ...}

Nếu bạn muốn validate serialize :

class TimesheetSetting < ApplicationRecord
  serialize :optional_settings, Hash
  ...
  validates :optional_settings, presence: true, if: :valid_optiettingsings

  private
  def valid_optiettingsings
    add_meassge_time_in_error if valid_time_in?
    add_meassge_time_out_error if valid_time_out?
  end

  def valid_time_in?
    optional_settings[:time_in].blank?
  end

  def valid_time_out?
    optional_settings[:time_out].blank?
  end

  def add_meassge_time_in_error
    errors.add :optional_settings, :blank, message: "time in not blank"
  end

  def add_meassge_time_out_error
    errors.add :optionoutsettings, :blank, message: "time out not blank"
  end

  ...

Ngoài ra chúng ta có thể sử dụng gem validate serialized

gem "validates_serialized"
$ bundle

Validating a serialized hash by keys

class TimesheetSetting < ApplicationRecord
  serialize :optional_settings, Hash
  ...

  validates_hash_keys :optional_settings do
    validates :time_in, presence: true
    validates :time_out, presence: true
    ...
  end

  ...
end

Validating a generic object

class TimesheetSetting < ApplicationRecord
  serialize :infor_company, Company

  validates_serialized :infor_company do
    validates :name, presence: true
    validates :address, presence: true
    ...
  end

  ...
end

Validating a serialized array

class TimesheetSetting < ApplicationRecord
  serialize :infor_company, Array
  ...
  #c1
  validates_array_values_with :infor_company, presence: true

  #c2
  validates_each_in_array :infor_company do
    validates :value, presence: true
  end
  ...
end

Link tham khảo: https://github.com/brycesenz/validates_serialized


All rights reserved

Viblo
Hãy đăng ký một tài khoản Viblo để nhận được nhiều bài viết thú vị hơn.
Đăng kí