Rails でQR コードを出力する必要がありました。要求は以下の3点。
- 普通のビュー内でも使いたい
- QR コードだけポップアップする機能も欲しい
- Controller でsend_data + ビューでlink_to(..., :popup => [...])
- PC で表示できればok
Helper 内でもControler 内でも使いたいので簡単なモジュールを作成。
使い方
普通にビューで使う場合
- application_helper.rb
def qrcode_url(str, size = 150) qrcode = ChartUtility::GoogleChart::QRCode.new(size) qrcode.url = str qrcode.to_url end
- example.erb.html
<%= image_tag(qrcode_url('http://d.hatena.ne.jp/')) %>
QR コードだけポップアップさせる場合
- example_controller.rb
def qrcode qrcode = ChartUtility::GoogleChart::QRCode.new(150) qrcode.url = 'http://d.hantena.ne.jp/' send_data(qrcode.to_data, :type => 'image/png', :disposition => 'inline') end
- example.erb.html
<%= link_to 'QR コード', {:action => 'qrcode'}, {:popup => ['QRCode', 'height=150, width=150']} %>
ソースコード
require 'net/http' require 'nkf' require 'uri' Net::HTTP.version_1_2 module ChartUtility module GoogleChart class Base attr_reader :type, :size def self.base_uri URI('http://chart.apis.google.com/') end def initialize(type, size) @type = type @size = size.kind_of?(Integer) ? "%sx%s" % [size, size] : size end def to_uri(options = {}) construct_uri.to_s end alias_method :to_url, :to_uri def to_data data = '' begin uri = construct_uri http = Net::HTTP.new(uri.host) http.open_timeout = 5 http.read_timeout = 5 http.request_get(uri.request_uri) do |res| data = res.body end rescue TimeoutError => ex ensure return data end end private def construct_params { :cht => @type, :chs => @size } end def construct_uri uri = self.class.base_uri uri.path = '/chart' uri.query = construct_params. sort_by{|k, v| k.to_s }. map{|k,v| "#{k}=#{URI.encode(NKF.nkf("-w", v.to_s)).gsub(/%20/,"+").gsub(/%7C/,"|")}" }.join('&') uri end end class QRCode < Base attr_accessor :url, :choe def initialize(size) super('qr', size) end private def construct_params choe = @choe || 'UTF-8' super.merge(:chl => @url, :choe => choe) end end end end