QR codes are an essential part of modern technology. They allow us to easily transfer information from one device to another. In this blog post, we will explore how to generate a QR code with Ruby on Rails using Active Storage and the gem "rqrcode."
Before we begin, let's make sure we have everything we need.
Create a new rails project named qr-code
rails new qr-code
Add the rqrcode gem to the gem file by running the command below :
bundle add rqrcode
Generate a scaffold for a Post model
rails g scaffold post title body:text
This command generates several files that make it easy to quickly create a functional CRUD (Create, Read, Update, Delete) interface for managing Posts in our web application.
Here's what each part of the command does:
-
rails
is the command to run Ruby on Rails. -
g
is short for "generate." -
scaffold
tells Rails to generate a complete set of files for a model, including a controller, views, and a migration. -
post
is the name of the model we want to generate. -
title
andbody:text
are attributes of the Post model. "title" is a string attribute, and "body" is a text attribute.
By generating a scaffold, we can quickly create a functional interface for managing Posts in our Rails application, saving time and effort. However, it's important to note that the generated code may not be perfect for our specific needs, and we may need to modify it to fit our requirements
Now let's install active_storage:
run the command bellow :
rails active_storage:install
The is command is used to install and set up Active Storage in a Ruby on Rails application. Active Storage is a built-in framework for managing file uploads and attachments in Rails applications.
At this point of the project, we can now create our database, migrate all tables.
rails db:create
rails db:migrate
Before running the server, we need to set the default URL options for the Rails action controller by specifying the host and port that the application should be running on.
To do so add the following line to your development.rb
file under config/environments/
# config/environments/development.rb
config.action_controller.default_url_options = { host: "localhost:3000", port: 3000 }
The begining of your file should look like in the following code snippet
# config/environments/development.rb
require "active_support/core_ext/integer/time"
Rails.application.configure do
# Settings specified here will take precedence over those in config/application.rb.
config.action_controller.default_url_options = { host: "localhost:3000", port: 3000 }
# In the development environment your application's code is reloaded any time
# it changes. This slows down response time but is perfect for development
# [... more code below ...]
end
Now you can start the application server by running the command bellow:
rails server
Now open your browser and navigate to http://localhost:3000, you should see the interface below
If you can see the above interface in your browser, that means you are ready to start, if not, you can go back and follow all the steps for better understanding. ♻♻
- As we have everything working, open you
routes.rb
file under/config/
directore and set the root path for the application:
# config/routes.rb
Rails.application.routes.draw do
root "posts#index"
resources :posts
end
Go to app/models/post.rb
and add the attach the qrcode
to the post model
# app/models/post.rb
class Post < ApplicationRecord
has_one_attached :qrcode, dependent: :destroy
end
The code above Ruby on Rails ActiveRecord association method that defines a one-to-one attachment association for our post model.
The has_one_attached method is provided by the Active Storage library, and it enables attaching a single file to the post model. This attachment is stored in a separate table in the database, and the association is handled by Active Storage.
- 👌 Good to know 👌: Overall, this code allows you to attach a single file to the post model, and ensures that the attachment is properly managed and cleaned up when needed. This is useful for cases where you need to store and manage file attachments within your Rails application.
Add the :qrcode
in the strong parameters method (post_params) used to whitelist and filter the parameters passed to a create action.
- Go to
app\controllers\posts_controller.rb
and make sure it looks like the following :
class PostsController < ApplicationController
# app\controllers\posts_controller.rb
# [ ... ]
# Only allow a list of trusted parameters through.
def post_params
params.require(:post).permit(:title, :body, :qrcode)
end
end
Implement the before_commit in the Post model
- Follow the [rqrcode] gem(https://github.com/whomwah/rqrcode) documentation to set everthing and after make sure that your
post.rb
file underapp/models/
looks like the following :
# app/models/posts.rb
class Post < ApplicationRecord
include Rails.application.routes.url_helpers
has_one_attached :qrcode, dependent: :destroy
before_commit :generate_qrcode, on: :create
private
def generate_qrcode
# Get the host
# host = Rails.application.routes.default_url_options[:host]
host = Rails.application.config.action_controller.default_url_options[:host]
# Create the QR code object
# qrcode = RQRCode::QRCode.new("http://#{host}/posts/#{id}")
qrcode = RQRCode::QRCode.new(post_url(self, host:))
# Create a new PNG object
png = qrcode.as_png(
bit_depth: 1,
border_modules: 4,
color_mode: ChunkyPNG::COLOR_GRAYSCALE,
color: "black",
file: nil,
fill: "white",
module_px_size: 6,
resize_exactly_to: false,
resize_gte_to: false,
size: 120,
)
# Attach the QR code to the active storage
self.qrcode.attach(
io: StringIO.new(png.to_s),
filename: "qrcode.png",
content_type: "image/png",
)
end
end
For the above code snippet I define a generate_qrcode method that generates a QR code for the post and attaches it to the qrcode association using Active Storage.
Here's a brief summary of what the code does:
The Post model
- Includes the Rails.application.routes.url_helpers module, which provides helper methods for generating URLs in Rails.
The before_commit :generate_qrcode, on: :create
callback
- Runs the generate_qrcode method before the post is committed to the database on creation.
The generate_qrcode
method
Generates a QR code for the post and attaches it to the qrcode association using Active Storage.
Uses the Rails.application.config.action_controller.default_url_options[:host] configuration value to get the host name for the current Rails application.
Generates a QR code using the RQRCode::QRCode.new method, passing in the post's URL as a string.
Uses the qrcode.as_png method to generate a PNG image of the QR code.
Attaches the QR code image to the qrcode association using Active Storage.
👌Good to know👌: Overall, this code generates a QR code image for a new post and attaches it to the post using Active Storage. The QR code can then be used to link to the post's URL, making it easy to share the post with others.
You can copy the above code and ajust it to your.
Here we go,
- As now we have generated our qr-code, let's display it on the post page.
Open the _post.html.erb
partial file under app/views/posts/
and add an image_tag for the qrcode as follow :
# app/views/posts/_post.html.erb
<div id="<%= dom_id post %>">
<p>
<strong>Title:</strong>
<%= post.title %>
</p>
<p>
<strong>Body:</strong>
<%= post.body %>
</p>
<%= image_tag(url_for(post.qrcode)) %>
</div>
- Now save you project and create a new post on the browser. After creation you should see the qr-code displayed on the web page as the one on the image bellow :
Now you might need to test that qr-code.
There are several ways to test this and from your browser just
open the site webqr and make sure your camera is filming your screen.Or just use the qr-code reader of your phone.
In conclusion, generating QR codes is now an essential part of modern technology as it allows us to easily transfer information from one device to another.
In this blog post, we have learned how to generate a QR code with Ruby on Rails using Active Storage and the gem "rqrcode". By following the step-by-step guide provided in the post, we were able to create a functional CRUD interface for managing Posts in our web application, and also learned how to install and set up Active Storage in a Ruby on Rails application.
Finally, we attached a qrcode to our post model using Ruby on Rails ActiveRecord association method, added the :qrcode in the strong parameters method (post_params), and whitelisted and filtered the parameters passed to a create action.
Github : qrcode-generator
Documentation : rqrcode
Overall, this post provides an excellent guide for anyone looking to generate QR codes using Ruby on Rails.
Top comments (4)
no point in adding the strong params here
params.require(:post).permit(:title, :body, :qrcode)
Thank you for that insight,
Gona check it out and update the post if neccessary
It works like a charm, thank you for your contribution!
Thank you kevin S.