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
コピペ用の進捗バー
css
.progressbar { width: 100%; height: 20px; margin-bottom: 20px; overflow: hidden; background-color: #f5f5f5; border-radius: 4px; -webkit-box-shadow: inset 0 1px 2px rgba(0,0,0,.1); box-shadow: inset 0 1px 2px rgba(0,0,0,.1); .progress { background-color: #5cb85c; height: 20px; &-0 { width: 0%; } &-20 { width: 20%; } &-40 { width: 40%; } &-60 { width: 60%; } &-80 { width: 80%; } &-100 { width: 100%; } } }
html
<div class="progressbar"> <div class="progress progress-0"> <div class="progressbar"> <div class="progress progress-20"> <div class="progressbar"> <div class="progress progress-40"> <div class="progressbar"> <div class="progress progress-60"> <!-- (略) -- >
イメージ
ジーニアスバーでは教えてくれなかったワイモバイルのsimでiPhone8に乗り換えてAPN設定してもネットが使えない問題の解決法
問題
ワイモバイルのiPhone5SからsimフリーiPhone8に乗り換えるとネットが使えなかった 公式のプロファイルを入れたけど、ネットに繋がらなかった。 simはn141
解決方法
iOS用APN構成プロファイルジェネレータで非公式なプロファイルを作る 注意点としてsafariでアクセスすること。(chromeでアクセスしてもできない) iOS用APN構成プロファイルジェネレータ
項目は以下の通り
APN: kqtqjs ユーザー名: tnsrknk パスワード: cmtknrn 認証タイプ: PAP
プロトコル、プロキシは空欄でOK
で再起動。
再起動してなかったために1時間近く手間取った。。。 電波の名前はymobileになるかとおもったけどsoftbankのままだった
非公式プロファイルなので自己責任で
slimテンプレートに変えた時にkaminariでhtmlが表示される
症状
途中からslimテンプレートに変えたらhtmlが表示されるようになった
解決方法
app/view/kaminari/_paginator.html.slim
を書き換える
デフォルト
= paginator.render do ul.pagination = first_page_tag unless current_page.first? = prev_page_tag unless current_page.first? - each_page do |page| - if page.left_outer? || page.right_outer? || page.inside_window? = page_tag page - elsif !page.was_truncated? = gap_tag = next_page_tag unless current_page.last? = last_page_tag unless current_page.last?
修正後
= paginator.render do ul.pagination == first_page_tag unless current_page.first? == prev_page_tag unless current_page.first? - each_page do |page| - if page.left_outer? || page.right_outer? || page.inside_window? == page_tag page - elsif !page.was_truncated? == gap_tag == next_page_tag unless current_page.last? == last_page_tag unless current_page.last?
Railsでパソコンとスマホでviewを分ける
Gemfile
gem 'rack-user_agent'
app/controllers/application_controller.rb
上でbefore_actionで判定させる。
before_action :check_user_agent_for_mobile
判定のメソッド
def check_user_agent_for_mobile if request.from_smartphone? request.variant = :mobile end end
view
index.html.erb
がPCで表示されてindex.html+mobile.erb
がSPで表示されるようになる。
AWS EC2のiptableとSELinuxをオフにする
EC2でRailsのサイト公開してもアクセスできなかった原因
初期状態
$ getenforce
Enforcing
効いている。
$ sudo service iptables status
Table: filter Chain INPUT (policy ACCEPT) num target prot opt source destination 1 ACCEPT all -- 0.0.0.0/0 0.0.0.0/0 state RELATED,ESTABLISHED 2 ACCEPT icmp -- 0.0.0.0/0 0.0.0.0/0 3 ACCEPT all -- 0.0.0.0/0 0.0.0.0/0 4 ACCEPT tcp -- 0.0.0.0/0 0.0.0.0/0 state NEW tcp dpt:22 5 REJECT all -- 0.0.0.0/0 0.0.0.0/0 reject-with icmp-host-prohibited Chain FORWARD (policy ACCEPT) num target prot opt source destination 1 REJECT all -- 0.0.0.0/0 0.0.0.0/0 reject-with icmp-host-prohibited Chain OUTPUT (policy ACCEPT) num target prot opt source destination
効いている。
SELinuxのオフ
$ vi /etc/selinux/config
SELINUX=enforcing
を
SELINUX=disabled
にする
iptable
$ sudo service iptables stop
carrierwaveのテンプレ
いまさらながらだが、、、一応rails5
Gemfile
gem 'carrierwave' gem 'rmagick'
controler
$ rails g uploader image
app/uploaders/image_uploader.rbが作成される
$ rails g controller image
app/controllers/images_controller.rbが作成される
modle
$ rails g model image --skip-migaration
invoke active_record create app/models/image.rb invoke test_unit create test/models/image_test.rb create test/fixtures/images.yml
DB
ridgepoleなのでSchemafileに
create_table "images", force: true do |t| t.string "path" t.datetime "created_at" t.datetime "updated_at" end
を追加してridgepoleコマンド
準備終了
ここまでで一通りファイル作ったからあとは書くだけ
app/models/image.rb
class Image < ApplicationRecord mount_uploader :path, ImageUploader end
app/controllers/images_controller.rb
class ImagesController < ApplicationController def upload image = Image.create(path: params[:file]) respond_to do |format| format.html { render json: {path: image.path.url}} format.json { render json: {path: image.path.url}} end end end
config/routes.rb
post '/image/upload' => 'images#upload'
app/views/topics/_form.html.erb
$(document).on 'turbolinks:load', -> $('input.js-upload-image').on 'change', -> fileList = @files i = 0 l = fileList.length while l > i fileReader = new FileReader fileReader.onload = -> dataUri = @result return fileReader.readAsDataURL fileList[i] i++ formData = new FormData formData.append 'file', $('input.js-upload-image')[0].files[0] jQuery.each $('input.js-upload-image')[0].files, (i, file) -> $.ajax url: '/image/upload' type: 'POST' data: formData cache: false processData: false contentType: false context: this success: (msg) -> msg = JSON.parse(msg) domains = msg.path.split('/') filename = domains[domains.length - 1] hostname = window.location.origin console.log hostname + msg.path $('input#office_thumb').val hostname + msg.path return return
app/assets/javascript/topics.coffee
<div class="form-group"> <%= form_tag image_upload_path, multipart: true do %> <%= file_field_tag 'image', class: 'js-upload-image' %> <% end %> </div>
Railsで使ってるckeditorにボタン追加する
したいこと
wordpressのadd quick tagみたいにボタン押すとhtmlがテキストエリアに入るようにしたい
英語ばっかだったから日本語でメモ
ckedior
gem
リファレンス
やり方
app/assets/javascripts/ckeditor/config.js
CKEDITOR.editorConfig = function( config ) { config.extraPlugins = 'defaulttable'; config.toolbar = 'MyToolbar'; config.toolbar_MyToolbar = [ ['Defaulttable'], [ 'Source', '-', 'Save', 'NewPage', 'Preview', 'Print', '-', 'Templates' ], [ 'Cut', 'Copy', 'Paste', 'PasteText', 'PasteFromWord', '-', 'Undo', 'Redo' ], [ 'Find', 'Replace', '-', 'SelectAll', '-', 'Scayt' ], [ 'Form', 'Checkbox', 'Radio', 'TextField', 'Textarea', 'Select', 'Button', 'ImageButton', 'HiddenField' ], '/', ['Bold', 'Italic', 'Underline', 'Strike', 'Subscript', 'Superscript', '-', 'RemoveFormat' ], [ 'NumberedList', 'BulletedList', '-', 'Outdent', 'Indent', '-', 'Blockquote', 'CreateDiv', '-', 'JustifyLeft', 'JustifyCenter', 'JustifyRight', 'JustifyBlock', '-', 'BidiLtr', 'BidiRtl', 'Language' ], [ 'Link', 'Unlink', 'Anchor' ], '/', [ 'Image', 'Flash', 'Table', 'HorizontalRule', 'Smiley', 'SpecialChar', 'PageBreak', 'Iframe' ], [ 'Styles', 'Format', 'Font', 'FontSize' ], [ 'TextColor', 'BGColor' ], [ 'Maximize', 'ShowBlocks' ], [ '-' ], [ 'About' ], [ 'car-table' ] ]; };
config.extraPlugins
で追加するプラグインの名前(プラグインのjsファイルを置くディレクトリ名になる)を指定
config.toolbar_MyToolbar
の一番初めに'Defaulttable
を追加
app/assets/javascripts/ckeditor/plugins/defaulttable/plugin.js
ディレクトリに気をつける。
CKEDITOR.plugins.add('defaulttable', { init: function (editor) { var pluginName = 'defaulttable'; editor.ui.addButton('Defaulttable', { label: 'My New Plugin', command: 'InsertTable', icon: 'http://www.hogehoge.com/images/hoge.png' }); var cmd = editor.addCommand('InsertTable', { exec: InsertTable }); } }); function InsertTable(e) { e.insertHtml('<table><tr><td>hoge</td></tr><tr><td>hoge</td></tr></table>' ); }