Skip to content

Reading a example Ruby PORO class #17

Description

@byhbt

Ruby PORO quite confuse me sometimes, let talk a look at this example:

class TardisMotoForm
  # Include the ActiveModel
  include ActiveModel::Model
  include ActiveModel::Validations::Callbacks

  # Define a custom constant
  PASSWORD_FORMAT = /(?=.*\d)(?=.*[a-z])(?=.*[A-Z])/

  # Define attr_accessor, so we can expose these attributes to the outside world
  # take a look more on attr_reader and attr_accessor
  attr_accessor :user, :email, :password, :phone_number, :transfer_type, :params, :taken_email, :params

  # Use the validation of model
  validate :email_uniqueness
  validates :password, presence: true, format: { with: PASSWORD_FORMAT }, length: { in: Devise.password_length }, if: :transfer_by_email?
  validates :email, email: { validate_mx: false }
  phony_normalize :phone_number
  validates :phone_number, phony_plausible: true

  # Define a custom method for the outside world can invoke
  # For example, in the controller
  # if @tardis_moto_form.valid_params?(filtered_fun_params)
  #   redirect_to somewhere_path
  # else
  #   render :new
  # end
  def valid_params?(params)
    assign_attributes(filter_params(params)) # where the assign_attribute come from?
    valid? 
  end

  # In the controller
  # if @tardis_moto_form.save(filtered_fun_params, resource) && resource.persisted?
  # end
  def save(attributes = {}, user = nil)
    @user = user # What is the user here? - it will assign to the attr user above
    @params = attributes

    user.errors.empty?
  end

  private

  # Model validation callback
  def transfer_by_email?
    transfer_type.to_sym == :email
  end

  # Model validation call back
  def email_uniqueness
    return unless User.exists?(email: email)

    @taken_email = true
    errors.add(:email, I18n.t('activerecord.errors.models.transfer_form.taken_email'))
  end

  # Sanitize filter params before assign attribute 
  def filter_params(params)
    {
      email: params[:email],
      password: params[:password],
      phone_number: params[:phone_number],
    }
  end
end

Reference:

Metadata

Metadata

Assignees

No one assigned

    Labels

    RubyLearning Ruby on Rails

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions