Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Reading a example Ruby PORO class #17

Open
byhbt opened this issue Sep 28, 2020 · 1 comment
Open

Reading a example Ruby PORO class #17

byhbt opened this issue Sep 28, 2020 · 1 comment
Labels
Ruby Learning Ruby on Rails

Comments

@byhbt
Copy link
Owner

byhbt commented Sep 28, 2020

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:

@byhbt byhbt added the Ruby Learning Ruby on Rails label Sep 28, 2020
@byhbt
Copy link
Owner Author

byhbt commented Sep 28, 2020

Then let extract the usage of attr_accessor into a smaller example:

class TardisMotoForm
  attr_accessor :user, :params

  def save(attributes = {}, user = nil)
    @user = user
    @params = attributes

    user.errors.empty?
  end
end

Here we have three user text:
:user: define user attribute of the class, which can be access from the outside world.
@user: for assign user into attribute :user as define in attr_accessor.
user: method params will assign to instance variable @user.

For a class we can have these kinds of attribute:

  • attr_reader
  • attr_writer
  • attr_accessor

References:

@byhbt byhbt changed the title Ruby PORO Reading a example Ruby PORO class Sep 28, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Ruby Learning Ruby on Rails
Projects
None yet
Development

No branches or pull requests

1 participant