Rails Generate Custom Secret Key

Posted on  by
  1. Rails Secret Key Base
  2. Rails Generate Custom Secret Key West
  3. Rails Generate Custom Secret Key Generator

Mar 24, 2018  In Rails 5.1 there were two files secrets.yml.enc and secrets.yml and it was creating confusion for our beloved SECRETBASEKEY. To remove this dilemma Rails core team decided to remove those two files and having only one file where you can store your all secret stuff like AWS key, database password, API keys and whatever which you want to make. Dec 18, 2012  Recently I had to build one Rails app off a clone of another Rails app. I wanted to find a quick way to change the secret token in config/initializers/secrettoken.rb. Rails provides rake secret for just this purpose. The source code is here. The code simply requires SecureRandom and spits out a string. If you want to be really clever, you can pipe the string directly into your Vim buffer for the config file, with.! You need to add a line to your config/initializers/devise.rb to set the secret key (replace the example value below with a more secure and random key): config.secretkey = 'yoursecretkey' After that just stop your Rails server and start it again. Also see this Stackoverflow question.

Rails is all about Convention over Configuration, this includes the DB primary key,which is always set to be id column. What if you want to use different columnas your primary key? Read on and I’ll show you how.

NOTE: This article is written for Rails 4.1.1 /w Postgres

Usecase

My webstore uses a special string ID, called sku, this ID is unique and queriedinstead of id column. For the sake of simplicty, I use Rails scaffolding:

What is primary key?

A column is called a primary key when it is:

  • has not NULL constraint
  • has UNIQUE contraint
  • has index

We could prove this by checking out DB schema:

The above output clearly indicates that at DB level, is is NOT NULL, is PRIMARY_KEY and indexed.

According to Postgres doc, PRIMARY_KEY constraint is a combination of a unique constraint and a not-null constraint.

Migration

We have following migration:

and we want to turn the sku column to be our primary key.

By convention, you would not see any code mention about the primary id column.This column is automatically created when you call method create_table.

We can tell Rails not to create column id by parsing id: false options

and then we tell Rails to turn sku to be primary key. After doing abit of research,I found method ActiveRecord::ConnectionAdapters::TableDefinitiion#primary_key withfollowing code:

Disecting the above shows that by using type primary_key, I could turn my column to primary key.I wonder what this type is. Let’s give it a go:

after rake db:migrate, I check my DB schema again:

The sku column is assigned with integer datatype, which is not correct. So primary_key type must be of integer type.

Rails generate secret

Naively, I try other alternatives:

OR

which doesn’t do anything. Meh :(

It is okay, if Rails doesn’t let you do so, because you can still be able to do a workaround:

and bravo, it does the job! Hold on, there is a twist!

our db/schema.rb says nothing about the contraint addition line, which makessense because we are not using SQL format to preserve it.

I don’t like this solution because I love readability of helper methods than SQL.

I come up with better solution (IMHO), according to Postgres documentation:

“a primary key constraint is simply a combination of a unique constraint and a not-null constraint”

Let’s see how I do it:

and let’s check our schema:

License key generator online. Though our sku doesn’t have PRIMARY_KEY contrsaint, yet it is equivalent.

And look at our db/schema.rb:

All lovely and readable ;)

Model

We tell our model Product to use sku as primary key:

Generate

And you are set to go.

Now I wonder if changing to different primary key, would it cause any side effectto method like #find. The answer is not at all, if we look into ActiveRecord::AttributeMethods::PrimaryKey:

the read_attribute(self.class.primary_key) line tells us that it will reference toour Product.primary_key, that is sku. Therefore, we you call:

Rails Secret Key Base

it would generate SQL:

and FYI, there is also writer method #id= that is provided by Rails:

If you don’t like to use #id and #id=, you could override them in your class:

Be aware that Product.find won’t work anymore, and other Rails helper that relieson id will stop functioning. If you really want that, you need to override moremethods and this seems too much of a pain for me. So I’d highly recommend you toleave #id as is.

Our default rails is:

which by default will generate routes with reference to :id:

With Rails 4, you can change :id to :sku with:

our routes would be:

Please be noted that you need to modify the ProductssController to find Order recordwith params[:sku] instead of params[:id].

Rails Generate Custom Secret Key West

URI

For example if we have a Product with a very non-URI friendly SKU like: ‘SKU 001’,when we access our ProductsController#show, we would have following URL:

to make our primary key URI friendly, we could override #to_param method. Byconvention, Rails would call this method to work out the routing URI:

and the URI turns to:

Rails Generate Custom Secret Key Generator

Conclusion

Rails is all about CoC, for most of the cases, you should stick to it. However you couldoverride the convention by:

  • Adding NOT NULL and UNIQUE contrainst to column you want to be the primary key
  • Set self.primary_key for the model
  • Set param for your routing
  • Override #to_param for friendly URI

That’s all for today. Please leave comments if you have any question.