menu
The test() method of JavaScript executes a search for a match between a regular expression and a specified string. If the match is found, it will return true. Otherwise, it will return false.

export const displayRoute = (route: string, t: (key: string) => string): string => {  
  const accountDetailRegex = /^\/accounts\/[0-9a-fA-F-]{36}$/;
if (accountDetailRegex.test(route)) return t('accountDetails'); };

In this example, we received a route and parsed it in regex to test() to verify whether it matched the possible characters of the routes. 

You could use a regular expression with .replace() to match everything from the start of your string up until the first dot ., and replace that with an empty string.

var str = "P001.M003.PO888393"; 
var res = str.replace(/^[^\.]*\./, '');
console.log(res);

Output: 
#=> M003.PO888393

usePathname is a Client Component hook that lets you read the current URL's pathname.

'use client'

import { usePathname } from 'next/navigation' 

export default function ExampleClientComponent() {  
  const pathname = usePathname()  
  
  return <p>Current pathname: {pathname}</p>
}

usePathname intentionally requires using a Client Component. It's important to note Client Components are not a de-optimization. They are an integral part of the Server Components architecture.

A interesting way to use it is like to modify the classNames in active routes as:

<Link 
  key={link.name}
  href={link.href}            
  className={clsx(              
     'flex h-[48px] grow items-center justify-center gap-2 rounded-md bg-gray-50 p-3 text-sm font-medium hover:bg-sky-100 hover:text-blue-600 md:flex-none md:justify-start md:p-2 md:px-3',
    {               
      'bg-sky-100 text-blue-600': pathname === link.href,
     },            
    )}         
   >            
   <LinkIcon className="w-6" />            
     <p className="hidden md:block">{link.name}</p>          
</Link>

The Law of Demeter belongs to the principle that states in a ruby method of an object should invoke only the methods of the following kinds of objects:
  1. itself
  2. its parameters
  3. any objects it creates/instantiates
  4. its direct component objects

The law restricts how deeply a method can reach into another object’s dependency graph, preventing any one method from becoming tightly coupled to another object’s structure.

Multiple Dots

The most obvious violation of the Law of Demeter is “multiple dots,” meaning a chain of methods being invoked on each others’ return values.

class User
  def discounted_plan_price(discount_code)
    coupon = Coupon.new(discount_code)
    coupon.discount(account.plan.price)
  end
end

The call to account.plan.price above violates the Law of Demeter by invoking price on the return value of plan. The price method is not a method on User, its parameter discount_code, its instantiated object coupon or its direct component account.

The quickest way to avoid violations of this nature is to delegate the method:
class User
  def discounted_plan_price(discount_code)
    account.discounted_plan_price(discount_code)
  end
end

class Account
  def discounted_plan_price(discount_code)
    coupon= Coupon.new(discount_code)
    coupon.discount(plan.price)
  end
end

In a Rails application, you can quickly delegate methods using ActiveSupport’s delegate class method:
class User
  delegate :discount_plan_price, to: :account
end

If you find yourself writing lots of delegators, consider changing the consumer class to take a different object

I use polymorphic routes for readability purposes. This is useful to make the lines of code a bit shorter like this:

<%= button_to "Delete", [quote, line_item_date] %>
<%= button_to "Delete", quote_line_item_date_path(quote, line_item_date) %>

It is also possible to use them in controllers. For example, the two following lines for code are equivalent:

redirect_to @quote
redirect_to quote_path(@quote)


If you want to learn more about them, here is a link to the documentation.

Syntactic sugar refers to the little bit of ✨ magic ✨ Ruby provides you in writing easier to read and more concise code. In Ruby this means leaving out certain symbols, and spaces or writing some expression with a helper of some kind one of these possibilities is the sandwich method, we look more at it here: 

It is common when we begin to handle an array in a each to do it specific actions thing like that:
array = [1, 2, 3, 4]
new_array = []
array.each do |element|
  new_array << element * 2
end
new_array
# => [2, 4, 6, 8]

Today I learned how simplified it is to handle this type of interaction by thinking about this magic we talked about before. the first thing that is important here is to remember that the use of each handle and return the same array and for this reason, it is necessary to create a new_array variable to inject the new values of the product to element * 2

Most of the time, if you have to use the sandwich method, there is probably a higher-level iterator that you could use that will allow you to perform the function on the array or hash without using the sandwich method. In this case, your best bet would be map :

array = [1, 2, 3, 4]
array.map do |element|
  element * 2
end
# => [2, 4, 6, 8]


If you need to capitalize only the first word of a sentence use the first-letter property for that.

.your_class_name::first-letter{
  text-transform: capitalize;
}

This was useful to me to capitalize data from an API and can't handle it on the base app.




To get a value and the index of this element into an array is useful this method, for example:

[11,22,31,224,44].each_with_index { |val,index| puts "index: #{index} for #{val}" if val < 30}
  index: 0 for 11
  index: 1 for 22
  => [11, 22, 31, 224, 44]
What is a JSON Web Token?

A JSON Web Token is an internet standard defined by the Internet Engineering Task Force (IETF) as a: "compact, URL-safe means of representing claims to be transferred between two parties" so, go ahead with the configuration.

Build the Rails app:
rails new jwt_rails_api --api


Add the gems:
gem 'jwt', '~> 2.7'
gem "bcrypt", "~> 3.1.7"

Generate User and Product Models
rails g model User username:string password:string
rails g model Product name:string description:text

After running our migration with rails db:migrate, our setup with models is complete, and our schema, found in db/schema.rb, should now look similar to this:

ActiveRecord::Schema[7.0].define(version: 2024_03_26_224534) do
  create_table "products", force: :cascade do |t|
    t.string "name"
    t.text "description"
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
  end

  create_table "users", force: :cascade do |t|
    t.string "username"
    t.string "password_digest"
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
  end
end


Build a jwt Gem Wrapper

Our wrapper class is found in app/lib/json_web_token.rb and looks like this:

class JsonWebToken
  JWT_SECRET = Rails.application.secrets.secret_key_base

  def self.encode(payload, exp = 12.hours.from_now)
    payload[:exp] = exp.to_i

    JWT.encode(payload, JWT_SECRET)
  end

  def self.decode(token)
    body = JWT.decode(token, JWT_SECRET)[0]

    HashWithIndifferentAccess.new(body)
  end
end

At this point, you can already test this class in your Rails console:

data = {"name"=>"Juanequex"}

JsonWebToken.encode(data)
# => "eyJhbGciOiJIUzI1NiJ9.eyJuYW1lIjoiQXBwU2lnbmFsIiwiZXhwIjoxNjg1NDI0MjI5fQ.zWJyFHH8Pa6phBOU99XgtRntyfZQSOTX4TdwOxFY9gY"

JsonWebToken.decode(JsonWebToken.encode(data))
# => {"name"=>"Juanequex", "exp"=>1685424262}


Back to the User Model
Now will be a good time to visit our User model at app/models/user.rb. All we need to do here is add the has_secure_password class method:

class User < ApplicationRecord
  has_secure_password
end

Creating a Sample User and Product in Rails is possible through the Rails console or configuring your seeds.
User.create(username: "juanequex", password: "password")
Product.create(name: "Rad Ruby", description: "A book collection of Ruby tips")



Using JWTs in Rails Controllers

 A good place to start is the ApplicationController at app/controllers/application_controller.rb:

class ApplicationController < ActionController::API
  before_action :authenticate

  rescue_from JWT::VerificationError, with: :invalid_token
  rescue_from JWT::DecodeError, with: :decode_error

  private

  def authenticate
    authorization_header = request.headers['Authorization']
    token = authorization_header.split(" ").last if authorization_header
    decoded_token = JsonWebToken.decode(token)

    User.find(decoded_token[:user_id])
  end

  def invalid_token
    render json: { invalid_token: 'invalid token' }
  end

  def decode_error
    render json: { decode_error: 'decode error' }
  end
end

Next, we need an AuthenticationController to which users can send requests and get a signed JSON Web Token from our server. This controller should be placed at app/controllers/authentication_controller.rb and may look like this:

class AuthenticationController < ApplicationController
  skip_before_action :authenticate

  def login
    user = User.find_by(username: params[:username])
    authenticated_user = user&.authenticate(params[:password])

    if authenticated_user
      token = JsonWebToken.encode(user_id: user.id)
      expires_at = JsonWebToken.decode(token)[:exp]

      render json: { token:, expires_at: }, status: :ok
    else
      render json: { error: 'unauthorized' }, status: :unauthorized
    end
  end
end


Testing Our Ruby Application with a Protected Resource
Let's create a controller with rails g controller Product index so we have something like:
class ProductsController < ApplicationController
  before_action :authenticate

  def index
    @products = Product.all

    render json: @products
  end
end

Of course, we need a route to access these controllers. Our config/routes.rb should look something like:
Rails.application.routes.draw do
  post 'login', to: "authentication#login"
  get 'products', to: "products#index"
end


Let's try getting a JWT with a user that doesn't exist:
curl -H "Content-Type: application/json" -X POST -d '{"username":"manny","password":"password"}' http://localhost:3000/login


We should get the following response:
{"error":"unauthorized"}


Now try the same with a user that we created earlier:
curl -H "Content-Type: application/json" -X POST -d '{"username":"juanequex","password":"password"}' http://localhost:3000/login


This should give us a signed JSON web token that could look like this:
{"token":"eyJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoxLCJleHAiOjE2ODU0NTEyMTR9.1UEYAbmFOSF93yp9pJqNEzkdHr3rVqutPNZWRIPDYkY","expires_at":1685432077}

Let's keep this token for a second and try accessing a product resource with a bad token (I changed a random character in the token):
curl -H "Authorization: Bearer eyJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoxLCJleHAiOjE2ODU0NTEyMTR9.1UEYAbmFOSF93yp9pJqNEzkdHr3rVqutPNZWRIPZYkY" http://localhost:3000/products

output:
{"decode_error":"decode error"}



However, if we make the same request to access the product resource with the valid token we got from the server previously, We're granted access to the product resource:

[{"id":1,"name":"Rad Ruby","description":"A book collection of Ruby tips","created_at":"2024-03-26T19:33:30.826Z","updated_at":"2024-03-26T19:33:30.826Z"}]

That's it! We've successfully secured our Ruby application with a JSON web token!
Rails 7 fresh apps ships with Turbo to speed up your application while dramatically reducing the amount of JavaScript that you will need to write.

Turbo lets your server deliver HTML directly as an alternative to the prevailing front-end frameworks that reduce the server side of your Rails application to little more than a JSON API.

Turbo has our back and has a built-in replacement for the browser's default progress bar, and we can style it to meet our application's design system!

set this style:
// app/assets/stylesheets/components/_turbo_progress_bar.scss

.turbo-progress-bar {
  background: linear-gradient(to right, var(--color-primary), var(--color-primary-rotate));
}

// app/assets/stylesheets/application.sass.scss

// All the previous code
@import "components/turbo_progress_bar";

debug step:
# app/controllers/application_controller.rb

class ApplicationController < ActionController::Base
  # Add this line to see the progress bar long enough
  # and remove it when it has the expected styles
  before_action -> { sleep 1 } # this is only to debug the progress bar, it can be removed.
Through the Heroku PostgreSQL add-on create a new backup capture you can do that by the UI or the CLI running:

heroku pg:backups:capture -a your-production-name-app

and after that run:

heroku pg:backups:restore <production-database-name>::<you-backups-id> DATABASE_URL --app <production-staging-enviroment> --confirm <production-staging-enviroment>

example:

heroku pg:backups:restore juanequex-prod::b194 DATABASE_URL --app juanequex-staging --confirm juanequex-staging

Enjoy! c:
Through the Heroku PostgreSQL add-on create a new backup capture you can do that by the UI or the CLI running:

heroku pg:backups:capture -a your-production-name-app

After that download the backup on your local machine, and set it in your local environment running on the terminal:

pg_restore --verbose --clean --no-acl --no-owner -h localhost -d <data-base-name> /Users/juanequex/backups/<your-local-backup>

and it is what it is, enjoy your local debugging.

" Hello world ".strip # => "Hello world"
Deletes all Jobs in a Queue, by removing the queue.

Sidekiq.redis(&:flushdb)
Using the following command, you can minimize any app on your Mac

cmd + m