Railsで多言語対応する
トップページを多言語化するサンプルコードのメモ
Gemfile
gem 'rails-i18n' gem 'http_accept_language'
config/routes.rb
Rails.application.routes.draw do scope '(:locale)', locale: /#{I18n.available_locales.join('|')}/ do root 'top#index' end end
config/application.rb
require_relative 'boot' require 'rails/all' Bundler.require(*Rails.groups) module CwSystem class Application < Rails::Application config.load_defaults 5.1 config.i18n.available_locales = %i(ja en fr es pt) config.i18n.enforce_available_locales = true config.i18n.default_locale = :ja end end
app/controllers/application_controller.rb
class ApplicationController < ActionController::Base protect_from_forgery with: :exception before_action :set_locale def set_locale I18n.locale = locale end def locale @locale ||= params[:locale] || I18n.default_locale || http_accept_language.compatible_language_from(I18n.available_locales || I18n.default_locale) end def default_url_options return {} if params[:local].blank? {locale: locale} end end
app/helpers/application_helper.rb
module ApplicationHelper def i18n_url_for(options) if options[:locale] == I18n.default_locale options[:locale] = nil end url_for(options) end end
config/locales/
それぞれの言語のymlを作成
carrierwaveで画像名をユニークにした時にS3とDBでファイル名が異なる
問題
ファイル名をユニークにするために以下の処理をしていた
def filename p "#{SecureRandom.uuid}.#{file.extension}" if original_filename.present? end
がs3にcarrierwaveで画像アップ&DBに保存すると、s3とDBのファイル名が違っていた。
この人たちと同じ現象
原因
filenameメソッドが複数回呼ばれているため。 save前に2回、saveの後に1回の計3回呼ばれている。
解決方法
def filename "#{secure_token}.png" if original_filename.present? end protected def secure_token var = :"@#{mounted_as}_secure_token" model.instance_variable_get(var) or model.instance_variable_set(var, SecureRandom.uuid) end
Rspec導入
gem導入
group :development, :test do (略) gem 'rspec-rails' end
$ bundle install --path vendor/bundle
configファイル生成
$ rails generate rspec:install
.rspec spec/spec_helper.rb spec/rails_helper.rb
が生成される
.rspec編集
--warnings --color --format documentation --require spec_helper
application.rb
config/application.rb
config.generators do |g| g.test_framework :rspec, view_specs: false, helper_specs: false, routing_specs: false end
配列で出現回数が多い順にソート&上からX個取得をRubyで
ary.group_by { |e| e }.sort_by { |e, v| -v.size }.map(&:first)
でソート
ary.group_by { |e| e }.sort_by { |e, v| -v.size }.map(&:first)[0..9]
でトップ10
CKEditorのフォームにhtmlタグを貼ると記号がエスケープされる
問題
フォームに
<h3>hogehoge</h3>
と入れて保存して
cssで
h3 { font-size: 24px; }
みたいにやってもCSSは当たらない。
解決策
エスケープされて
<h3>hogehoge</h3>
の形で保存される。
app/assets/javascripts/ckeditor/config.js
if (typeof(CKEDITOR) != 'undefined') { CKEDITOR.editorConfig = function (config) { config.basicEntities = false; config.entities = false; } }
とすればOK
ちなみに
if (typeof(CKEDITOR) != 'undefined') { }
がないと、ckeditorのフォームが無いページで
uncaught ReferenceError: CKEDITOR is not defined
のエラーが出る
仮想通貨bot開発でよく見るやつメモ(随時更新)
全共通
これの中身みればだいたい分かる
bitflyer
ドキュメント lightning.bitflyer.com
bitmex
ドキュメント
ruby用ライブラリ github.com
binance
ドキュメント
deviseで招待用リンクを生成する(メールを使わずに招待機能を実装)
したいこと
- 招待用URLを発行できる
- メールを使わずにユーザーを招待できる
端折ること
- URLと発行したユーザーのリレーション
- 招待されたユーザーがどのURLから登録されたか
- URLの期限
- クリック数
実装
model
$ rails g model initation
migrationファイルは
class CreateInvitations < ActiveRecord::Migration[5.1] def change create_table :invitations do |t| t.string :token t.timestamps end end end
端折った機能作りたいならここでclick_count
なりlimited_at
なりを足す
controller
$ rails g controller users::invitations
routes.rb
namespace :users do resource :invitations, only: [:show, :update] end
を追加
invitations_controller.rb
class Users::InvitationsController < ApplicationController before_action :authenticate_user! def show if Invitation.count == 0 Invitation.create!(token: SecureRandom.uuid.gsub!(/-/,'')) @invitation_token_url = "http://localhost:3000/users/sign_up?tk=" + Invitation.all.last.token.to_s else @invitation_token_url = "http://localhost:3000/users/sign_up?tk=" + Invitation.all.last.token.to_s end end def update Invitation.create!(token: SecureRandom.uuid.gsub!(/-/,'')) @invitation_token_url = "http://localhost:3000/users/sign_up?tk=" + Invitation.all.last.token.to_s redirect_to users_invitations_path, notice: "URLを作成しました" end end
(注意)
- ここらへんheplerにまとめる。
- URLは
gem 'config'
でベタ打ちにしない
views/invitations/show.html.slim
.container-fluid .container .row .col-sm-12 h4 招待用URL作成 = text_field_tag '#', @invitation_token_url, class: 'form-control' .margin-top-30 = link_to 'URLを再作成する', users_invitations_path, { method: 'put', class: 'btn btn-primary' }
これとか入れる
registrations_controller.rb
ここで一番はじめのユーザー以外の直リンクと不正なtoken or token無しをはじく
class Users::RegistrationsController < Devise::RegistrationsController before_action :check_sign_up_token, only: [:new] (略) protected # 新規登録にtoken無しでアクセスさせない def check_sign_up_token return redirect_to root_path if params[:tk].nil? || User.count == 0 || !Invitation.exists?(token: params[:tk]) end end
アクセスした時にtokenをcookieに保存して、createの時にチェックするようにした方がよい(?)
deviseでユーザー招待機能の追加
したいこと
- 登録されているユーザーがメアドを入力して送信すると招待用URLが記載されているメールを送信できる
- 招待用URLを踏むとパスワード設定画面に遷移できる
- パスワードが完了すると登録が完了する
=>slackに招待用URLで人追加する時と同じ
前提
- deviseは導入済み
- deviseを適用しているモデルは
user
- viewとcontrollerもdeviseディレクトリでなくusersディレクトリ配下にある
- devise.rbは
config.scoped_views = true
になっている - 開発環境でのメール確認は
letter_opener
とletter_opener_web
を導入済み
実装方法
Gemfile
追加してbundle install
gem 'devise_invite'
rails command
$ rails generate devise_invitable:install $ rails generate devise_invitable user $ bundle exec rake db:migrate
models/user.rbの変更、migrationファイル、viewファイルができる
models/user.rb
これが既存
class User < ApplicationRecord devise :database_authenticatable, :registerable, :recoverable, :rememberable, :trackable, :validatable end
修正後
class User < ApplicationRecord devise :invitable, :database_authenticatable, :registerable, :recoverable, :rememberable, :trackable, :validatable, invite_for: 2.weeks end
routes.rb
devise_for :users, controllers: { sessions: 'users/sessions', passwords: 'users/passwords', registrations: 'users/registrations', invitations: 'users/invitations' # 追加 }
確認
http://localhost:3000/users/invitation/new
にアクセスして、メールフォームにメアドを入れて送信すると、root_pathにリダイレクトする。- シークレットブラウザで
http://localhost:3000/letter_opener
にアクセスすると招待メールがきていて、"Accept invitation"を押すと、http://localhost:3000/users/invitation/accept?invitation_token=XXXXXXXXXXXXXX
に飛んで、パスワード設定画面が表示される。 - パスワードを設定するとログインできる
参考URL
railsの開発でメール送信テスト
gemfile
developmentのグループに以下を追加
gem 'letter_opener' gem 'letter_opener_web'
routes.rb
以下を追加
mount LetterOpenerWeb::Engine, at: '/letter_opener' if Rails.env.development?
development.rb
config/environments/development.rb
以下を追加
config.action_mailer.delivery_method = :letter_opener_web config.action_mailer.default_url_options = { host: 'localhost', port: 3000 }
動作確認
http://localhost:3000/users/password/new
にアクセスしてパスワードリセットのメールを送信してみる。
http://localhost:3000/letter_opener
にアクセスすると送信されたメールの一覧が見れる
enumを日本語化するenum_help
topic.rb
class Topic < ApplicationRecord enum status: { draft: 0, published: 1, privated: 2 } end
gem
gem 'enum_help'
ja.yml
config/locales/ja.yml
ja: enums: topic: status: draft: 下書き published: 公開 privated: 非公開
application.rb
config/application.rb
config.i18n.default_locale = :ja
を追加
RailsにreCAPTCHAを導入する
問題
問い合わせフォームにスパムが多くなったのでreCAPTCHAを入れる
サイト登録
www.google.com にアクセスして「Get reCAPTCHA」をクリック
「Register a new site」のフォームに必要事項を入力 Site keyとSecret keyが出る。
注意点としては「Domains」にはサイトのURLとlocalhost
を追加すること
ambethia/recaptcha
github.com このgemを使う
導入
gem
dotenv-railsとrecaptchaを入れる
gem "recaptcha", require: "recaptcha/rails" gem 'dotenv-rails'
Gemfileに追加してbundle install
env
.env
RECAPTCHA_SITE_KEY='6Lxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' RECAPTCHA_SECRET_KEY='6Lxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
recaptcha.rb
config/initializers/recaptcha.rb
Recaptcha.configure do |config| config.site_key = ENV['RECAPTCHA_SITE_KEY'] config.secret_key = ENV['RECAPTCHA_SECRET_KEY'] # Uncomment the following line if you are using a proxy server: # config.proxy = 'http://myproxy.com.au:8080' end
view
form_forの中のreCAPTCHAを表示させたいところに追加する
= recaptcha_tags
認証されたcallbackを受け取ってsubmitボタンのdisable外したい時は
= recaptcha_tags callback: 'recaptchaCallbackFunction'
にする
controller
createメソッドに追加する
if verify_recaptcha(model: @contact) && @contact.save # 成功した時の処理(メール送信とか) redirect_to "/contact", notice: '送信成功' else render 'new' end
callbackを受けてdisable属性とdisableクラスを外す
application.js
var recaptchaCallbackFunction = function () { $('#js-recaptcha').removeClass('disable'); $('#js-recaptcha').prop('disabled', false); };
jsで追加した要素にイベントが発生しない
$(document).on 'click', '.tab-pane.active .image-garally img', -> console.log $(this) return
もしくは親要素の下のクラスという指定の仕方をするとうまく動く
$('.tab-pane.active').on 'click', '.image-garally img', -> console.log 'boxをクリックしました!' return
rake db:migrate:resetとrake db:seedをまとめて実行してくれるrake taskを作成
$ vi lib/tasks/db.rake
namespace :db do desc "Run 'db:migrate:reset' and 'db:seed'" task resetup: ['db:migrate:reset', 'db:seed'] end
fukajun/rails-db-resetupの github.com をコピペしただけ
ただstarの低いgemを入れたくなかっただけ
bundle installでcapybara-webkitのエラー
railsでcloneしてbundle install したらエラーがでた
An error occurred while installing capybara-webkit (1.7.1), and Bundler cannot continue. Make sure that `gem install capybara-webkit -v '1.7.1'` succeeds before bundling.
解決方法
macのバージョンがmacOS Sierraなのでこれ https://github.com/thoughtbot/capybara-webkit/wiki/Installing-Qt-and-compiling-capybara-webkit#macos-sierra-1012-el-capitan-1011-and-yosemite-1010
$ brew install qt@5.5 $ echo 'export PATH="$(brew --prefix qt@5.5)/bin:$PATH"' >> ~/.bashrc $ brew link --force qt@5.5