RailsとCarrierWaveで画像アップロードを実装する
CarrierWaveというGemを使って画像のアップロードを実装しました。
今回はUserモデルのimageというプロパティーに画像をセットする実装をします。
CarrierWaveのインストール
CarrierWaveを入れる前にImageMagickをインストールします。
Macの場合は下コマンドでインストールします。
brew install imagemagick@6 brew install pkg-config export PKG_CONFIG_PATH=/usr/local/opt/imagemagick@6/lib/pkgconfig
ImageMagickを入れたらBundlerでcarrierwaveとrmagickを入れます。
gem 'carrierwave' gem 'rmagick'
CarrierWaveでファイルアップロード
最初にファイルのアップローダーを追加します。
追加は下コマンドで行います。
rails g uploader image
コマンドを打つと下のようなファイルが生成されます。(余計なコメントなどは削除)
画像のパスやサムネイル生成の有無などを変更したい時はこのファイルに設定を書きます。
class ImageUploader < CarrierWave::Uploader::Base storage :file def store_dir "uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}" end end
次にUserモデルを作成します。
scaffoldで一気に作ってしまいます。
rails g scaffold user image:string
usersテーブルのimageカラムはStringのままで構いません。
ここにはファイルのパスが入ります。
class CreateUsers < ActiveRecord::Migration def change create_table :users do |t| t.string :image t.timestamps null: false end end end
次はUserモデルにファイルアップロード用の処理を記述します。
user.rbに下のように1行追加します。
class User < ActiveRecord::Base mount_uploader :image, ImageUploader end
次はファイルのアップロード画面を実装します。
views/users/_form.html.erb
のフォーム周りの実装を修正します。
<%= form_for(@user) do |f| %> <% if @user.errors.any? %> <div id="error_explanation"> <h2><%= pluralize(@user.errors.count, "error") %> prohibited this user from being saved:</h2> <ul> <% @user.errors.full_messages.each do |message| %> <li><%= message %></li> <% end %> </ul> </div> <% end %> <div class="field"> <%= f.label :image %><br> <!-- 下2行を変更 --> <%#= f.text_field :image %> <%= f.file_field :image %> </div> <div class="actions"> <%= f.submit %> </div> <% end %>
これでファイルアップロード用画面ができました。
アップロードしたファイルは、ImageUploaderの設定に従ってpublic/uploads/user/image
以下に保存されます。
CarrierWaveで画像の表示
最後にアップロードしたファイルの表示を実装します。
views/users/show.html.erb
を下のように修正してください。
<p id="notice"><%= notice %></p> <p> <strong>Image:</strong> <!-- 下2行を変更 --> <%#= @user.image %> <%= image_tag @user.image.url %> </p> <%= link_to 'Edit', edit_user_path(@user) %> | <%= link_to 'Back', users_path %>
ブラウザで確認すると正しくファイルが表示されています。
参考URL
macOS に RMagick をインストールする
Rails 超お手軽な画像アップローダー CarrierWave の使い方 | Workabroad.jp
【iOS11】設定アプリ内にある自分のアプリの設定画面へ遷移する
iPhoneの設定アプリには、下のように自分のアプリの設定ページが用意されています。
今回はここへ直接遷移する方法について調べました。
自分のアプリの設定画面への遷移方法
遷移方法は下の通りです。
if let url = URL(string: UIApplicationOpenSettingsURLString) { UIApplication.shared.open(url, options: [:], completionHandler: nil) }
UIApplicationOpenSettingsURLString
は文字列型で、自分の設定ページへの遷移URLが入っています。
print(UIApplicationOpenSettingsURLString) // → app-settings:
Railsでcrontabを管理できるwheneverというGemを使ってみる
Railsを使っていると「日時バッチ」「1時間に一度の処理」など定期的に実行したいタスクが出てきます。
管理方法としては普通にcrontabに書き込んだりJenkinsなどを使ってそれらのタスクを管理する方法があります。
しかし可能ならRailsプロジェクト上で実行時間なども管理したいです。
そういった時に使えるGemがwheneverです。
これを使うと下のようにRubyでcrontabの管理ができます。
every :day, at: '12:20' do runner 'MyModel.execute' end every :sunday, at: '12:30' runner 'MyModel2.execute' end
wheneverを使う準備
インストールはBundlerを使います。
gem 'whenever'
インストールが終わったらwheneverizeコマンドでwheneverの初期化をします。
wheneverize
実行するとconfig/schedule.rbというファイルが作られます。
ファイルの内容は下の通りです。
# Use this file to easily define all of your cron jobs. # # It's helpful, but not entirely necessary to understand cron before proceeding. # http://en.wikipedia.org/wiki/Cron # Example: # # set :output, "/path/to/my/cron_log.log" # # every 2.hours do # command "/usr/bin/some_great_command" # runner "MyModel.some_method" # rake "some:great:rake:task" # end # # every 4.days do # runner "AnotherModel.prune_old_records" # end # Learn more: http://github.com/javan/whenever
wheneverの使い方
まずは先程作られたconfig/schedule.rbに定期実行したいタスクを書きます。
下は4日おきにMyModelのcreate!を呼び出すタスクです。
every 4.days do runner "MyModel.create!" end
タスクを書いたらcrontabにどんな形で書き込まれるか確認をします。
確認にはwheneverコマンドを使います。
whenever
wheneverコマンドを実行すると下のようにどのようにcrontabに書き込まれるかが表示されます。
crontabへの反映もwheneverコマンドを使います。
下のように--update-crontabを付けて実行します。
whenever --update-crontab
実行後crontab -lで確認するとしっかり書き込みができている事が分かります。
wheneverのフォーマット
wheneverではデフォルトでcommand, rake, runner, scriptというメソッドが用意されています。
実行結果はそれぞれ下の通りです。
every 4.days do command "bundle install" # → /bin/bash -l -c 'bundle install' rake "my_task" # → /bin/bash -l -c 'cd /Users/xxxx/Desktop/my_app && RAILS_ENV=production bundle exec rake my_task --silent' runner "MyModel.create!" # → /bin/bash -l -c 'cd /Users/xxxx/Desktop/my_app && bundle exec bin/rails runner -e production '\''MyModel.create!'\''' script "my_script" # → /bin/bash -l -c 'cd /Users/xxxx/Desktop/my_app && RAILS_ENV=production bundle exec script/my_script' end
自分で上記以外のメソッドを追加する事もできます。
job_type :my_job, "cd :path && :bundle_command rake :task" every 4.days do my_job "my_task" # → /bin/bash -l -c 'cd /Users/xxxx/Desktop/my_app && bundle exec rake my_task' end
実行時間の書き方も色々な種類があります。
下のように文字列でcrontabと同じ形式に書く事ができます。
非常に分かりやすい書き方です。
every '0 0,1,2 * * *' do # → 0 0,1,2 * * * runner 'MyModel.execute' end
毎日決まった時間に実行する場合は下のような書き方も分かりやすいです。
every :day, at: '12:20' do # → 20 12 * * * runner 'MyModel.execute' end
特定の曜日だけ実行する事もできます。
every :sunday, at: '12:30' do # → 30 12 * * 0 runner 'MyModel.execute' end
「アプリ開発のためのUX講座」まとめ
「アプリ開発のためのUX講座」という動画講座がとても面白かったので、学んだ事や感想をまとめてみました。
動画はSchooの有料会員限定ですが、資料は下URLから見る事ができます。
そもそもUXってなにか?
授業で初めて知ったんですが、実はUXはISOで定義されています。
授業では「サービスに接した時に感じるきもち」という形で噛み砕いて紹介されていました。
UXの種類
この授業ではUXを4種類に分けて紹介していました。
それぞれ下のような内容です。
予期的UX
サービスと接する前の体験。
「CMを見て気持ちが盛り上がる」「友達から紹介されてやりたくなる」など。
一時的UX
サービスを使って感じた体験。
「デザインがきれい」「アニメーションがおしゃれ」「特定の機能が便利だった」など。
エピソード的UX
サービス終了後の体験。
「使ってみて便利だった」「ゲームを遊んで楽しかった」など終了後に振り返る体験。
累積的UX
継続してサービスを使うことで起こる体験。
「ついつい起動してしまう」「次に使うのを心待ちにする」など。
これは一時的UXを積み重ねる事で起こる。
ユーザーに継続して使ってもらう為の工夫
ユーザーにサービスを継続利用してもらう為には、できるだけ強い「一時的UX」を体験してもらう事が重要だと紹介されていました。
弱い感動を連続して与えるのではなく、強い感動を与える事でファンになってくれる人が増えると話していました。
同時に、「一時的UX」をなるべく早く与える事も重要です。
「アプリ開発のためのUX講座」まとめ
「早く強い「一時的UX」を与える」という事を今まで意識してなかったので、目からウロコでした。
今まで自分は「使いにくい所を減らしてユーザーの離脱を防ぐ」って事を考えてアプリを作っていたので、これからは「どこで感動してもらうか」という事も考えようと思いました。
それからUXを4つに分類した事も面白かったです。
今までは「一時的UX」しか意識してなかったので、今後余裕があれば他のUXについても考えてみたいと思います。
はてなブログの過去記事にカテゴリーを付ける
はてなブログの過去記事にカテゴリーが全然付いてなかったので付ける事にしました。
カテゴリーなしは百記事以上あるので少しでも楽になるように工夫しつつ実施しました。
まずはエントリー一覧ページに移動します。
https://blog.hatena.ne.jp/llcc/llcc.hatenablog.com/entries
全ての記事を一気に直したいので「次のページ」をひたすら押して全部の記事を出します。
押し続けるのが大変な下コードを実行します。
$(".js-load-next-page").click()
次に「カテゴリーなし」のものだけ表示するようにします。
機能としては用意されてないので下コードを実行します。
$("tr").filter(function() { return $(this).find(".blog-category-name").length == 1 }).each(function() { $(this).remove() })
これでカテゴリーがないものだけを取得できたので地道に一括カテゴリー設定をしていきます。
LAContextのbiometryTypeがnoneになる問題
LAContextクラスのbiometryTypeプロパティーを使うと端末が指紋認証に対応しているか顔認証(FaceID)に対応しているかを判定する事ができます。
LAContext().biometryType == .faceID LAContext().biometryType == .touchID
LAContextのbiometryTypeで起こった問題
しかし顔認証対応の端末で上のコードを実行してもtrueになりません。
LAContext().biometryType == .faceID // → false LAContext().biometryType == .touchID // → false LAContext().biometryType == .none // → true
LAContextのbiometryTypeで顔認証を判定する方法
判定するためには、canEvaluatePolicy
メソッドを一度実行する必要があります。
こうすればfaceID対応している端末かを判定できます。
let context = LAContext() var error: NSError? if context.canEvaluatePolicy(.deviceOwnerAuthenticationWithBiometrics, error: &error) { print(context.biometryType == .faceID) // → true }
ドキュメントの方にもcanEvaluatePolicy
が呼ばれたタイミングで値がセットされると書かれています。
This property is set when canEvaluatePolicy has been called for a biometric policy. The default value is LABiometryTypeNone.
指紋認証だとどうなるか
iPhone8など、指紋認証対応している端末で検証しても同じような結果になりました。
LAContext().biometryType == .faceID // → false LAContext().biometryType == .touchID // → false LAContext().biometryType == .none // → true
UnityでスクリプトからTexture2Dを読み込む(C#)
UnityでSpriteのTextureをスクリプトで動的に変更する方法です。
Textureの配置場所
読み取りたいTextureはResourcesフォルダに入れる必要があります。
詳しくは下ページのResourcesに載っていました。
Textureの読み込み
Textureの読み込みは下の通りです。
Resources.Load
を使って先程配置したTextureを読み込んでいます。
テクスチャのパスにはフォルダ名(Resources)は含める必要はありません。
(Texture2D)Resources.Load($"enemies/enemy1");