Juncture

Introduction

Hi there, recently I have been facing a lot of issues with juncture. Since I want to be an expert in Ruby on Rails let’s see the main functions. In my developper’s life I have seen mainly three differents things for juncture as for now. (Note that this post can be updated and I’ll add the other juncture I’ll face in the future)

def left_joins
def left_outer_joins
def joins

For the three methods, you can find their definitions in on api.rubyonrails.org, here, here and here.

left_join is simply an alias for the function left_outer_joins so we killed one. 2 Lefts.

left_outer_joins is pretty simple, as the doc say :

If you want to select a set of records whether or not they have associated records you can use the left_outer_joins method.

As the function is called, this is an OUTER_JOIN (🤦‍♂️ 😂). This is a short definition :

External juncture to return all the records in the left table. Even if the condition is not verified in the other table.

Basically it means that an OUTER JOIN will always return the values that have or not an associations.

The subtility with the OUTER JOIN is that you’ll probably endup with duplicates especially dealing with has_many association. For example you have a Delivery has_many Articles. Multiple Articles reference the same Delivery so you’ll have duplicates.

left-outer-join

1 Lefts.

The final one joins is an INNER_JOIN juncture. What does that mean ?

This command return the records when there are at least one line in each columns whom matches to the condition.

inner-join

If you understand the concept, there’s no duplicate here, the query will return only the object that have an associations.

A singleton used for configuration couple with store_accessor

Hey guys today I wanna talk about something I encounter during the project I am working on in my company. We’ll see what is a singleton (as a reminder) and how to implement it with an hstore feature. The advantage of this is having dynamical attributes rather than a migration.

The singleton is a class that can be instantiated only once. This is pretty cool for a logger or configuration for the web. Another use for mobile development is a singleton RESTClient, you can invoke from everywhere and fetch data. Most of the example on the internet are with ruby, this is cool in theory but let’s see how to accomplish this in practice with Rails. We will have one model representing the singleton.

shop_configuration.rb

class ShopConfiguration < FftServerModel
  include ShopConfigHash
  validate :must_be_singleton, on: :create

  private

  def fill_with_default
    self.config_hash =
      self.class.default_config.
      merge((config_hash || {}).delete_if { |_key, value| value.nil? })
  end

  def must_be_singleton
    errors.add_to_base :must_be_singleton if ShopConfiguration.any?
  end

  class << self
    def singleton
      record = first || new
      record.fill_with_default
      record.save! if record.new_record? || record.changed?
      record
    end
  end
end

Here we have a singleton class. We call it through ShopConfiguration.singleton. The validation makes it a singleton : there’s only one class configuration in the project. If we try to create two configurations class, an error will throw. Note that we use add_to_base to add the error.

shop_config_hash.rb

module ShopConfigHash
  include Shipping

  included do
    store_accessor :config_hash, *default_config.keys
  end
end

This is where the magic happen. Basically when you’ll do something like ShopConfiguration.singleton.parcel_preparation_ref_validation_method it will executes the equivalent of ShopConfiguration.singleton.config_hash.parcel_preparation_ref_validation_method. The store_access function is in charge to write the value of our content and read it directly in the attribute passed in parameters, i.e the config_hash. If you take a look on how the store_accessor function is implemented : it defines a setter / getter method and make these function retrieve / set the value from the attribute set as first parameter, i.e config_hash. You should think of store_accessor as just a shortcut when you call any method, instead of searching for this method at the instance level like a regular attribute, it will go and search inside the given attribute.

store.rb

  def store_accessor(store_attribute, *keys)
    keys = keys.flatten

    _store_accessors_module.module_eval do
      keys.each do |key|
        define_method("#{key}=") do |value|
          write_store_attribute(store_attribute, key, value)
        end

        define_method(key) do
          read_store_attribute(store_attribute, key)
        end
      end
    end

One last thing, if you take a look at the snippet below with the splat operator, passing *default_config.keys as parameter is just splitting the array of key into multiple argument. Basically it means this :

def go(x, y)
end

point = [1, 2]
go(*point)

common.rb

module ShopConfigHash::Common
  extend ActiveSupport::Concern

  class_methods do
    attr_reader :default_config

    private

    def key(name, type, default: nil)
      @default_config ||= {}
      @default_config[name] = default

      define_singleton_method(name) do
        singleton.send(name)
      end

      define_method :"#{name}=" do |value|
        clazz = "ActiveModel::Type::#{type.capitalize}".constantize
        super(clazz.new.cast(value))
      end
    end
  end
end

This code is reusing the same principle as store_accessor. All calls like ShopConfiguration.my_attribute will be forwarded to the singleton class method (an instance of ShopConfiguration) When you do ShopConfiguration.parcel_preparation_ref_validation_method it will call ShopConfiguration.singleton.parcel_preparation_ref_validation_method.

If you follow the article, this call is forwarded to the config_hash attribute. When you do ShopConfiguration.parcel_preparation_ref_validation_method as getter or setter you actually call ShopConfiguration.singleton.config_hash.parcel_preparation_ref_validation_method.

One last useful thing to notice is the cast defined in the setter method. What happen is we call on the fly, the ActiveModel::Type::Boolean for example and cast the value.

shipping.rb

module ShopConfigHash::Shipping
  extend ActiveSupport::Concern
  include ShopConfigHash::Common

  included do
    key :parcel_preparation_ref_validation_method, :string

    key :parcel_preparation_ref_validation_strict, :boolean, default: false

    validates :parcel_preparation_ref_validation_strict,
              inclusion: { in: [ true, false ] }
    validates :parcel_preparation_ref_regex,
              presence: true, if: :parcel_prep_ref_regex_validation_method?    
  end

  private

  def parcel_prep_ref_regex_validation_method?
    parcel_preparation_ref_validation_method == 'Regexp'
  end
end

This is the final use of the function where you can hard code your attribute. I found this approach really interesting because it allows to split your attributes per file and defined validation for each of them, no needs to have a migration. It can be really useful when you have a ton of settings you don’t want to use.

Idempotent

Hi there, just a quick article about the “idempotent” concept in computer-science. I’ll show you what it mean by using the PUT and PATCH concept in HTTP. Let’s make a quick summary about those two :

[…] The existing PUT method only allow a complete replacement of a document.

[…] This proposal adds a new HTTP methods, PATCH to modify an existing HTTP resource.

Basically what it means is that the PUT needs the entire object in parameters. The PATCH allow to modify partially the object.

Idempotent: the principale of idempotent is that an operation producted one or N times will always product the same output.

For PUT this is very simple : since we update an the object entirely with the newly given data, the change producted one times or N times will always be the same and return the same things from the server.

For PATCH, this is a bit shady - this is a bit more difficult. Everything depends on the API’s format input.

If we gave it something like :

PATCH '/user/42' { name: foo }

Then yes patch is idempotent. If we recall one or N time the method then we will have the same result. Why ? Because we assume that PATCH is used like PUT be we simply give as parameters the fields we want to update, in another words, it’s simply a customized PUT. But most of the example on the internet are talking about PUT and PATCH and idempotence because PATCH can be used in a different way. We can imagine the following format for our API :

PATCH '/calculator' { field: count; operation: inc }

In this case the operation is not idempotent because we can imagine the server having an error until a certain number.

To be honest so far in my experience I have never seen the use of PATCH with this format, so I am not sure this is the “best” example we can give to most of the people, but we do understand now the principle of idempotence : PUT will always return the same thing because we update the object entirely and if the data are correct one time, they will be safe the next time, however, using PATCH for incrementing a variable or sending a signal can lead to different scenarii depending on how much times we call the API and the constraint applied to the counter.

Virtual attributes

I recently face an issue in my job where I was suppose to create a resource, N times. A first approach is to use the default params object used in controller to send a variable containing the number of time the object should be created. However, since the creation of the object should be done through another model, a second approach could be to use virtual attributes. The idea behind a virtual attributes is that this is an accessor / attributes of the model which is not persistant in the database. We could then fill it with a form.

Just before going in the code here is the scenario: we are going to create an object EpcOrder, which should create N times another object GtinEpcOrder.

Step 1, the form.

form.html.erb

<%= f.input :gtins_count, as: :integer %>
<%= f.input :description, as: :text %>
<%= f.submit %>

The first thing to do is create a form to fill the model. Here the description is a persistant attributes of the model, while gtins_count is the virtual attributes, we call it that way but really there’s no convention, what matter is that the name has to match with the vitual attributes defined in the model. (See just below)

Step 2, the model.

epc_order.rb

class EpcOrder < ApplicationRecord
  validates :gtins_count, numericality: { only_integer: true, greater_than: 0, less_than_or_equal_to: 10.000 }
  attribute :gtins_count, :integer, default: 0
end

gtins_count is the virtual attribute. I was using at first the attr_accessor ruby keyword to defined the getter / setter of the attributes, but I discovered the attributes keyword which is introduced in rails 5. Both options are the same and work, simply make sure you specify in your HTML form the type if this is not a string, in our case gtins_count is an integer.

Step 3, the controller.

epc_orders_controller.rb

class Admin::EpcOrdersController < Admin::AdminController
  def create
    @epc_order = EpcOrder.new(epc_params)
    if @epc_order.save
      # success steps
    end
  end

  private

  def epc_params
    params.require(:epc_orders).permit(:description, :gtins_count)
  end  
end

This is the controller of the resource, the important thing to see here is we add the gtins_count variable in the permitted params of the model.

Once the three steps has be done, you can simply use the attributes like if it is part of the model :

Step 4, the model, again.

epc_order.rb

class EpcOrder < ApplicationRecord
  after_create :create_gtins

  def create_gtins
    gtins_count.times do
      GtinEpcOrder.create
    end
  end
end

Rails - routes

Small notes

In computer science a path is relative whereas a url is absolute In rails you’ve got helper to have your user navigating into differents link.

One of the key differences between the path and url helper are as the rails guide said :

photos_path returns /photos
photos_path returns /photos
new_photo_path returns /photos/new

Each of these helpers has a corresponding _url helper (such as photos_url) which returns the same path prefixed with the current host, port, and path prefix.

To recap the situation you will probably have relative url (_path) in view while you’ll be using _url helper in controller with redirect_to. Another use of _url helper is for email template, it is a bit like a redirect a the end : you need to make your user naviguating from one place (the email inbox) to another (your website, or another one)

Search