Today I Learned

A CCSalesPro project TwitterFollow on Twitter

12 posts about #rails

Change rails server binding with ENV vars

You can change the rails server binding with an environment variable in addition to the CLI flags using the variable BINDING:

BINDING="::" rails server

Strict local variables

Rails partials let you do strict local variables with a magic comment:

<%# app/views/customers/_customer.html.erb %>
<%# locals: (customer:) -%>
<%= customer.name %>

If you don't pass a customer to the parital, it will raise an error:

<%= render "customer", not_customer: 42 %>

You must pass the customer:

<%= render "customer", customer: %>

Rails can give the ordinal of any number

Integer's have an #ordinalize method that returns a string:

34.ordinalize + " street"
=> "34th street"

Create a date duration from a string

Rails can parse ISO8601 date durations (PnYnMnDTnHnMnS) or ranges compatible for postgres daterange types:

ActiveSupport::Duration.parse("P1Y3M2D").parts
=> {:years=>1, :months=>3, :days=>2}

Get the last quarter in Rails

Rails' Date like objects have a method to get to the next or previous quarter:

Date.current.last_quarter.beginning_of_month
=> Sun, 01 Oct 2023

Turbo frame will be in the request headers

If a request was made with a data-turbo-frame attribute, there will be a header turbo-frame with the same value:

<a data-turbo-frame="my-container" href="/promo">Click here</a>

There will be a header attached to the fetch request:

class Controller
  def promo
    puts request.headers["turbo-frame"]
    # => "my-container"
  end
end

How to enable email previews in production

You can enable email previews in production, but be aware that these routes are public and have no authentication requirements, but you could do that with an upstream proxy.

# config/environments/production.rb
config.action_mailer.show_previews = true

Change form validation attribute name

Using rails' i18n gem and a en.yml file you can change the attribute of a form object:

en:
  attributes:
    fname:
      one: "First name"

Then you will see the new attribute name:

<div>Errors:</div>
<div>First name can't be blank</div>

Set default form builder globally

You can set a form builder globally, for all forms, by setting the value of default_form_builder in ApplicationController:

class ApplicationController < ActionController::Base
  default_form_builder MyFormBuilder
end


https://api.rubyonrails.org/classes/ActionController/FormBuilder.html

Pluralize words without displaying a count

The pluralize method is very familiar in rails to do things like:

<div>
  <%= pluralize(users.size, "users") %>
</div>

to see something like <div>4 users</div>

But strings have a pluralize method too:

puts "User".pluralize(4)
=> "Users"

Add custom inflectors for irregular words

ActiveSupport::Inflector allows you to add custom inflections for words it doesn't know how to pluralize already:

# config/initializers/inflections.rb
ActiveSupport::Inflector.inflections(:en) do |inflect|
  inflect.irregular "evidence", "evidence"
  #   inflect.plural /^(ox)$/i, "\\1en"
  #   inflect.plural /^(ox)$/i, "\\1en"
  #   inflect.singular /^(ox)en/i, "\\1"
  #   inflect.irregular "person", "people"
  #   inflect.uncountable %w( fish sheep )
end

This allows us to use evidence as a table name with a model called Evidence

puts "evidence".pluralize
"evidence"

Use a custom subdomain in an integration test

In an integration test ActionDispatch::IntegrationTest, you are not using Capybara, so you can't use Capybara.app_host=, but you can use the host! method to change the host url_for uses:

class MyTest < ActionDispatch::IntegrationTest
  def setup
    host! "admin.lvh.me"
  end

  test "#index" do
    visit my_url
  end
end