主婦がアプリをリリースするまでの軌跡

自宅でお小遣い稼ぎをしたい主婦がアプリリリースを目指すブログです。

本年もご覧いただき有難うございました。

f:id:song-of-life1352607:20180115004800j:plain

こんにちは、マリンです。

2018年最後の投稿です。

いよいよ今年も残すところ12時間弱。

年々1年が短くなっている様に感じます〜(´༎ຶོρ༎ຶོ`)

来年は1日1日、1仕事1仕事、1コード1コード大事に、

毎日勉強していく!!!(つもりです…(≧∀≦))

では、本年も皆さま当ブログをご覧いただき、

誠にありがとうございました!

2019年も地味に更新して参る所存ですので、

どうぞよろしくお願い申し上げます。

皆さま良いお年をお迎えくださいm( )m

【Rails】Date型↔︎文字型変換

f:id:song-of-life1352607:20180314224659p:plain

こんにちは、マリンです。

最近よく日付関係を扱うことがよくあるのですが、

Date(日付)型と文字列型の変換方法をよく忘れるので、

備忘録としてここに書かせていただきます。





Date型 → 文字列型

Date型から文字列型への変換方法。

strftime

today = Date.today    # 2018-12-05  Date型の日付(変換前)
today.strftime("%Y年 %m月 %d日")    # "2018年 12月 05日"  文字列型の日付(変換後)

Date型のオブジェクトに対し、strftimeメソッドを使うことで文字列型に変換できます。

引数にフォーマットを指定することで、その指定通りの形に変換できます。

ちなみに、%Y%yにすると年の下二桁だけを出せます。




フォーマット一覧は以下の通りです。

*文字は基本的に英語表記です。

フォーマット 変換後の出力
%A 曜日の名称
%a 曜日の省略名
%B 月の名称
%b 月の省略名
%c 日付と時刻
%d 日(01-31)
%H 24時間制の時(00-23)
%I 12時間制の時(01-12)
%j 年中の通算日 (001-366)
%M 分(00-59)
%m 月を表す数字(01-12)
%p 午前または午後(AM,PM)
%S 秒(00-60 *60はうるう秒)
%U 週を表す数。最初の日曜日が第1週の始まり(00-53)
%W 週を表す数。最初の月曜日が第1週の始まり(00-53)
%w 曜日を表す数。日曜日が0(0-6)
%X 時刻
%x 日付
%Y 西暦を表す数
%y 西暦の下2桁(00-99)
%Z タイムゾーン
%% パーセント文字




文字列型 → Date型

文字列型からDate型への変換。

to_date

to_dateメソッドを使う。

str_today = "2018-12-05"    # 文字列型の日付(変換前) 
str_today.to_date    # Date型の日付(変換後)
=> Wed, 05 Dic 2018

to_dateは楽なのでよく使います。

ただ、西暦の下二桁のみには対応していません。


strptime

Date型のstrptimeを使う。

Date.strptime('2018-12-05', '%Y-%m-%d')    # (文字列型の日付, 日付を表すフォーマット)
=> Wed, 05 Dic 2018 




to_dateに比べたらちょっと複雑になりますが、

こちらは西暦下二桁のみにも対応可能です。

Date.strptime('18-12-05', '%y-%m-%d')
=> Wed, 05 Dic 2018




まとめ

日付についてはDateやらDateTimeやらいろいろあっていつも混乱します。

また取得したものがDateなのか文字列なのか?とか。

計算するときに型が違うとエラーになっちゃいますしね(汗)

日付に関する型の違いもいずれまとめられたらと思います。

【Git】git reset --hard HEADを取り消したい!!

f:id:song-of-life1352607:20180113002051p:plain

こんにちは、マリンです。

今日Gitでやらかしました。

表題の通りなのですが、それにプラスしてDBのロールバックとかも関わってきて、

「ギャーーーー!!!」

ってなったので残しておきます。





概要

やらかした内容が多すぎるので、時系列で箇条書きします。

  1. 新規でDBのテーブルを作成するのにrails g migration ~~で作ってしまった。

  2. テーブルを作った後しばらく作業を進めてからModelが無いことに気づく。(この間何度かcommitしてる)

  3. Modelだけ作れば良いところ、わざわざrake db:rollbackしようとした。

  4. だがロールバックする前に何を思ったかCommitをテーブル作る以前まで戻してしまった。

  5. しかもGitの取り消しをgit reset --hard HEAD@{n}でやってしまった。(ここが一番問題)

  6. ロールバックしようにも当然マイグレーションファイルまで消えてしまったのでできない。




やはり一番のやらかしポイントは、commitのやり直しで

git reset --hard HEAD@{n}

を使ってしまったことでしょう。

--hardオプションをつけると、ワーキングツリーまで変更されてします。

では、これに対する対処を次から書いていきます。


対処法

1、2、3まではおそらくModelファイルだけ作ってあげれば良かった話だと思うので省略します。

4、5、6について詳細と対処法を記載しようと思います。


そもそも何が起こったのか?

私が不用意に打ったgit reset --hard HEAD@{n}

これによって何が起こったのかを解説します。

飛ばしていただいて結構です。


$ git reset --hard HEAD^
  • git reset:これは任意のcommitを取り消すコマンドです。

  • --hard :resetコマンドのオプションです。コミットだけでなく、ワーキングツリーまで元の状態に書き換えます。

  • HEAD@{n} :HEADの位置をどこまで戻すかを指示しています。@{n}で遡ることn番目のcommitを表します。




問題は真ん中の--hardオプションです。

これによりワーキングツリーまで元の状態に戻ってしまったため、

テーブル作成のために書いたマイグレーションファイルまで消えてしまいました。

(今回はテーブル作成をする一つ前のコミットまで戻ったので・・・)

そしてこれをrake db:rollbackを実行する前にやってしまいました。

該当のマイグレーションファイルが無いのにロールバックしたってできるわけがありません。

なのでこの取り消し(git reset)を取り消して、マイグレーションファイルを復活させる!

それが今回の目標です。


ちなみに問題のオプションですが、

--softにを指定すればコミットだけをなかったことにしてくれます。

これにしていればアワアワすることもなかったでしょう・・・

他にもコミットとインデックスを取り消す--mixedもあります。

オプション無しのデフォルトもこれです。

こちらでより詳しく説明してくださっています。

[git reset (--hard/--soft)]ワーキングツリー、インデックス、HEADを使いこなす方法




コミット取り消しの取り消し

ここからが本題です。

消してしまった事実をなかったことにして、

マイグレーションファイルを復活させます。


$ git reflog
$ git reset --hard HEAD@{n}
$ git log

こちらが一連の流れです。

git reflog

まずどこまでコミットを戻すか履歴を見ます。

コマンドがgit logでない理由は、

リセットされたコミットはgit logの履歴に出てこないからです。

git reflogは消されたコミットも履歴として見ることができます。


git reset --hard HEAD@{n}

ここで取り消しを無かったことにします。

今回は--hardオプションで大丈夫です。

消えてしまったワーキングツリーのファイルを復活させたいので。

HEAD@{n}のnにはログで確認した該当コミットが現在地から何番目にあたるかの番号を入れてください。

reflogの時に番号入りで表示されるはずなのでわかりやすいと思います!


git log

最後に念のため確認をしましょう。

この場合はこちらの履歴で大丈夫です。

以上が解説になります。

なお、実例を交えたより詳しい説明をこちらでしてくださっていますので、

ぜひご覧ください。

git reset --hardした内容を取り消す (git reset --hard, reflog, HEAD@{x}, 取り消してしまったコミットを元に戻す) - いろいろ備忘録日記




まとめ

今までadd、commit、pushくらいしかやってこなかったGitです。

正直他のことはよくわからないから触りたく無かったし、

そもそも何ができるのかも曖昧でした。

しかし、今回初めて「履歴が残っている」ということの有り難みを感じました。

そしてむやみに手元まで変えてはならない!!ということも・・・

基本は--softでやるのが安全だし、一般的な様ですね。

大変勉強になりました!

【Bootstrap/Rails】popoverのdata-contentの中身をHelperに切り出してみた。

f:id:song-of-life1352607:20170220105406j:plain

こんにちは、マリンです。

今回はBootstrapのpopoverです。

popoverはtitleに表示するタイトル。data-contentに表示する内容を書きます。

でも長い内容をタグ内に書きたくないでしょ!

ってなわけでRailsのHelperにメソッド切って表示内容を切り出してみました。

注)HTML上ではベタ書きになっちゃいますけど。




概要

- 環境 -

Rails5

Bootstrap3


- 例に使うテーブル構造 -

Usersテーブル

  • id

  • name

Childrenテーブル

  • id

  • name

  • user_id




- 概要 -

Userの名前をクリックすると、

ポップオーバーでChildrenの名前が表示されるようにします。

この時data-contentの中身が複雑になるので、

Helperにメソッドを切ってそれをdata-contentに渡します。


詳細

そもそもなんでこんなことになるのか?ちょっと詳細を説明します。

まず前提として、対象のページはindex.html.erbで、

Userの名前はUser.alleachで回して表示しているとします。

さらにChildrenは複数いる可能性があります。


そこで問題となるのが、

  1. どのUserの子供であるかを特定するためにuserを渡す必要があること。

  2. Childrenはuser.childrenの配列になること。

  3. その配列から名前を取得して表示するには、ループを回す必要があること。




ポップオーバーの内容は複雑になる場合、別エリアに切り出すことも可能です。

しかし今回の場合、まず一番外側でUser.allをループしています。

切り出すにはこのループの外になるでしょう。

となると1番のどのUserかを特定するuserを渡すのが大変です。

Ajaxを駆使してコントローラに値を渡して〜・・・なんてことが予想されます。




2、3番は表示内容が複雑になる理由です。

てことでHelperにメソッドを切ってみてはどうか?となったわけです。

ちなみに子の名前は一人一人改行して表示します。

HTML上はベタ書きになってしまいますが、コードはすっきりします。


ソースコード

さて前置きが長くなりましたが、ここから本題です。

まぁやってることは真新しいことではないのですが・・・

ControllerとModelは特に特筆することはないので、コードだけで解説は省略します。

Controller

# controllers/users_controller.rb

def index
    @users = User.all
end




Model

# user.rb

has_many :children

# child.rb

belongs_to :user




View

<!-- views/users/index.html.erb -->

<% @users.each do |user| %>
    <button class="btn" data-html="true" data-toggle="popover" title="子ども" data-cotent="<%= children_popover(user) %>">
        <%= user.name %>
    </button>
<% end %>




まずbuttonタグの中にあるdata-html="true"をご覧ください。

今回のメソッド切り出しとは直接関係はありませんが、

これを入れることでポップオーバーの中で改行<br>を使うことができるようになります。




次に本題のdata-content="<%= children_popover(user) %>"です。

このerb表記の中身が、後述のHelperに切り出すメソッド名です。

引数にuserを渡していることにご注目ください。

別エリアへの切り出しではないため、大枠のループのuserをそのまま使うことができます。




Helper

# helpers/users_helper.rb

def children_popover(user)
    users_children = []
    user.children.each do |child|
        users_children << child.name
    end
    users_children.join("<br>")
end




まず最初に子どもの名前を入れる空の配列を用意します。

そしてuser.childrenのループを回し、

その中で名前を先ほどの配列に格納していきます。

最後にループの外で出来上がった配列を、

区切り文字に<br>改行を指定して返します。

これを使うために先ほどViewでdata-html="true"を指定しました。

解説は以上になります。


まとめ

今回は値の取得などにたいした時間がかからないものでしたのでこの方法を使用しました。

しかし、表示する値の取得に時間がかかるようでしたら、

やはり別エリアに表示内容を切り出し、

値の取得にはAjaxを使って行うなどの方法をとった方が良いかと思います。

私も機会がありましたら挑戦してみようと思います。

ちなみに、今回の検証でpopoverを使用するためにclass="btn"が必ず必要だったのですが、

これは仕様でしょうか?それとも私の設定ミスでしょうか?

どなたかわかる方いらっしゃいましたら是非教えてください。

よろしくお願い致します。

【jQuery】show/hide ~イベントによって表示・非表示を切り替える~

f:id:song-of-life1352607:20180113005923j:plain

こんにちは、マリンです。

今回はボタンクリックなどのイベントによって

簡単に要素の表示・非表示を切り替えようと思います。





概要

任意の要素の表示・非表示をボタンのクリックで切り替えます。

ボタンを押すと要素を非表示に、もう一度押すと表示させます。

詳細

Rails環境で行っているため、JSの記述はcoffee scriptです。

View

<!-- app/views/samples/index.html.erb -->

<div class="target-element" data-display="on">
    <p>この部分を切り替えます。</p>
</div>

<button type="button" class="btn btn-md btn-default switch-display">Switch</button>

<script>
    samples.switchDisplay();
</script>




上から順番に解説します。

<div class="target-element" data-display="on">
    <p>この部分を切り替えます。</p>
</div>

この部分が表示したり非表示にしたりする要素です。

target-elementjQueryでこの部分を特定するためのセレクタです。

data-display="on"は、現状が表示中かどうかを判定するためのものです。


<button type="button" class="btn btn-md btn-default switch-display">Switch</button>

表示・非表示の切り替えボタンです。

Bootstrapを使っているので、btnなどのクラスでスタイルを当てています。

switch-displayはイベントの対象となるセレクタです。


CoffeeScript

class SamplesController

    switchDisplay: ->
        $('.switch-display').on 'click', ()->
            if $('.targe-element').data('display') == 'on'
                $('.switch-display').data('display', 'off')
                $('.switch-display').hide()
            else
                $('.switch-display').data('display', 'on')
                $('.switch-display').show()
        return

this.samples = new SamplesController




上から順番に解説します。(class ~~については省略します)

$('.switch-display').on 'click', ()->
    if $('.targe-element').data('display') == 'on'

.switch-display(ボタン)がクリックされたら、

まず切り替え対象の要素の持つdata-displayの値が

onであるかそうでないか検証します。


$('.switch-display').data('display', 'off')
$('.switch-display').hide()

値がonの時、つまり表示状態の時には

data-displayの値をoffにし、

切り替え対象の要素をhide()で非表示にします。


else
   $('.switch-display').data('display', 'on')
   $('.switch-display').show()

値がoffので非表示状態の時には

data-displayの値をonにし、

切り替え対象の要素をshow()で表示にします。


まとめ

要点としては、

  • 切り替えの着火剤となるイベント

  • hideによる非表示

  • showによる表示

この3点です。

今回はイベントをクリックにしましたが、

hoverなどで自作のポップオーバーに使ったりなど

イベントを変えればいろいろと応用が効くと思います。

【Rails5】Rails5で自作のWebアイコンを使う

f:id:song-of-life1352607:20180314224659p:plain

こんにちは、まりんです。

うちの会社ではFontAwsomeがマストなんですが、

結構クライアントからこんなアイコン使って欲しい!といわれ、

そんなのねーよ!!という事が多々あるようです。

そしてこの前唐突に、上司から

アイコン作るスキル身につけて欲しいんだけど。

と言われました。

マジかよ!?

という事で、今回ちょっとやってみました。

「独自アイコンをWebアイコン化し、それをRails5で使ってみた。」

です。





概要

環境

使用アプリ

  • icomoon


今回は元素材はこちらでお借りしました。

icooon-mono.com

f:id:song-of-life1352607:20180709125300p:plain

使いたいアイコンのページからSVG形式でダウンロードしてください。


本当にアイコン作るところからやる場合は、

IllustratorInkscapeなど、SVGで出力できるアプリを使って作成して下さい。

(イラレは高いので私はInkscapeにしようと思っています。本業じゃないし。)


Webアイコン使用までの流れ

  1. 素材(SVG)をicomoonでWebアイコン化する

  2. Webアイコンをダウンロードして必要ファイルをアプリケーションに移動

  3. ファイルの移動先に合わせてダウンロードしたstyle.cssを書き換え

  4. assets/stylesheets/application.scssからimportで読み込む


詳細

それでは一つずつの詳細を説明します。

素材をWebアイコン化する

今回はicomoonというアプリを使って行います。

元となる素材をアップしてそこからダウンロードするだけでできるのでとてもお手軽です。


f:id:song-of-life1352607:20180709135805p:plain

①まずは左上のボタンから素材のファイルをアップロードします。

今回は1枚だけですが、複数アップロードすることが可能です。


②Webフォント化する素材を選択します。

ここでも複数選択が可能で、今後アプリで使用したいアイコンをまとめてダウンロードすれば、

オリジナルのアイコンリストを作れます。

今回はアップロードしたものの他に、追加したBrandsと言うライブラリのニンテンドーswitchのアイコンと、

デフォルトで表示されているIcoMoonのHomeアイコンを一緒にダウンロードしてみます。

*ちなみに写っていませんが、ページの一番下にライブラリ追加のリンクがあります。


③選択すると、下部の真ん中のSelectionの数が増えます。

④右下のボタンでWebアイコンを作成。

Webアイコン化するファイルの確認ページに飛びます。


f:id:song-of-life1352607:20180709140410p:plain

①ここで付いている名前がそのままアイコン使用時のクラス名になります。

アップロードしたアイコンが日本語になっているので編集します。

他にもアイコン画像をクリックすれば、拡大縮小や反転などの簡単な編集も可能です。

②編集、確認が終わったら右下のボタンでダウンロードして下さい。


必要ファイルをアプリケーションに移動

ダウンロードしたフォルダを解凍したら、必要なファイルをアプリケーションに移動します。

f:id:song-of-life1352607:20180709142837p:plain

必要なファイルは上記のfontsフォルダ下のものと、style.cssです。


railsアプリのvendor下に置きます。

vendorの中にassetsをまず作り、その下にfontsstylesheetsを作ります。

他にも何かダウンロードしたものを使うことがあるかもしれないので、

一応専用のフォルダをそれぞれ作ってそこに入れます。

  • vendor/assets/fonts/icomoon → fonts下のファイル

  • vendor/assets/stylesheets/icomoon → style.css




style.cssの書き換え

先ほど移動した構造に合わせて、ダウンロードしたstyle.css内のurlの部分を書き換えます。

f:id:song-of-life1352607:20180709150059p:plain

私はここの指定が不十分だったがために余計な時間や手間を使ってしまいました。

assetsなので、追加した専用フォルダ名からで大丈夫です。

*今回はRails5なのでconfigの方の設定は入りませんでした。

確認はしていませんが、もしかしたらRails4以下ではプリコンパイルなどの設定がいるかもしれません。

こちらで大変詳しく説明して下さっています。

qiita.com




application.scssで読み込む

最後にassets/stylesheets/application.scssからimportでライブラリを読み込みます。

f:id:song-of-life1352607:20180709150950p:plain

ここでも専用フォルダ名が必要になるのでご注意ください。

*直置きの場合は入りません。

以上で実際にviewで使用するまでの準備は完了です。


アイコンを使ってみる

viewでの使い方は、Font Awesomeなどのようにクラスにicon-~のアイコン名を入れて使います。

icomoonの場合は<span>にクラスをつけるようにしてください。

<div>
    <span class="icon-nightsky"></span>
</div>
<div>
    <span class="icon-home3"></span>
</div>
<div>
    <span class="icon-nintendoswitch"></span>
</div>

f:id:song-of-life1352607:20180709151743p:plain

無事表示できました。

まとめ

Webアイコン化して表示させるまでは簡単ですね。

問題はアイコンを作れるかどうかです。

画力も計算もデザイン能力も全く自信がないのですが。。。

それはさておき、途中にも書きましたがこれはRails5での方法になります。

Rails4以下ではvendorに置いたものをデフォルトで探してはくれなかったりするようなので、

おそらくconfig/initializers/assets.rbなどに設定する必要があるかと思います。


今回はこちらの記事を参考にさせていただきました。

machida.github.io

【jQuery (CoffeeScript)】属性の値に変数や式を使う 〜式展開の色々〜

f:id:song-of-life1352607:20180113005923j:plain

こんにちは、マリンです。

今回はjQueryでの式展開についてです。

よくdata属性で要素を絞り込む際の値に

事前に定義した変数を使いたい時があるのですが、

そんな時にいつも職場で使われている記述が理解できず、

色々ググってみたのに見つからない。。。

でも調べているうちに「はっ!!」と気付いたのです。

「これ、式展開だ!!」と。

ってことでこういった副題が付いています。笑





まず今回もRailsの中で検証してますので、

基本、記述方式はCoffeeScriptです。

では今回検証で使いました例のソースコードです。

# HTML
<ul id="lists">
  <li class="a" data-index="1">AAA</li>
  <li class="b" data-index="2">BBB</li>
  <li class="c" data-index="3">CCC</li>
</ul>
<button type="button" class="has-element">HasElement</button> 

# jQuery
$('.has-element').on 'click', () ->
      class_a = "a"
      index = 2

まあボタンはどうでもいいんですけど、

これ押すとコンソールに表示されるって使用でつけました。

このクリックイベントの中に後述の式展開を書いていく感じで。

以後そこのみ書いていきます。


jQueryでの式展開の色々

やり方は3つあります。

  • #{}

  • +

  • ,


#{}

これが純粋な式展開ではないかと思います。

[ソースコード]

// class属性で検索
classA = $('#lists').find("[class = #{class_a}]")
console.log(classA.text)

// data属性で検索
classB = $('#lists').find("[data-index = #{index}]")
console.log(classB.text)

// 展開部分の中で計算する
classC = $('#lists').find("[data-index = #{index + 1}]")
console.log(classC.text)

[実行結果]

AAA
BBB
CCC




それぞれ属性値の指定に、予め値を入れておいた変数を使用しています。

もちろんその中でさらに計算させることも可能です。


JSやjQueryでは' '" "を区別しないみたいなんですが、

これはcoffeeだからだなんでしょうね、

#{}の式展開はダブルクォーテーションの中じゃないと使えませんでした。


+

こちらは前後の文字列と+を使って連結する方法。

[ソースコード]

// class属性で検索
classA = $('#lists').find("[class = " + class_a + "]")
console.log(classA.text)

// data属性で検索
classB = $('#lists').find('[data-index = ' + index + ']')
console.log(classB.text)

// 展開部分の中で計算する
classB = $('#lists').find('[data-index =' + (index + 1) + ']')
console.log(classC.text)

実行結果は前回と同じです。


classBに注目していただきたいのですが、

これは単純に一つの文字列を前後に分け、

その間に変数を入れて繋げる方法ですので、

クォーテーションはシングルでもダブルでも大丈夫です。


その次のさらに計算をする方法ですが、

こちらは計算部分をカッコで囲ってください。

計算の順番が関係するということですね。

これをしないと左から順番通りに計算され、

前半の文字列にindexの中身が足されたものに+1をすることになり、

「は?」と怒られます。

正直、ここまでやってきて初めて計算の順番を意識しました。


,

最後は文字列の後ろに展開したものをくっつけるときに使えます。

文字列の間には入れられませんので、表題とはズレた番外編です。

[ソースコード]

# 値取得部分
classA = $('#lists').find("[class = #{class_a}]")

# 表示部分(展開)
console.log("classA: ", classA.text)

[実行結果]

classA: AAA




今回の展開部分は後半の

("classA: ", classA.text)の部分です。

文字列の後にカンマで区切ったclassA.textを展開してくっつけています。

変数の中身などを展開して文字列に連結しているので、

多分式展開の一種ではないかと思います。。。


まとめ

今回そもそもの問題だった「記述が理解できない」部分に関しては、

おそらく式展開の問題ではなく、コードの読解力だと思います。

真ん中のclassB = $('#lists').find('[data-index = ' + index + ']')

の記述でハマったのですが、

findのカッコ内が' 'で囲まれていた時点できちんと

文字列 + 変数という構造であることを理解できていればこんなことにはなりませんでした。

なぜか' + index +'という塊で捉えてしまったんですよね。


まぁおそらく私のような間違いを犯す人はいないと思いますが、

式展開の方法は一つではないとわかっていれば、

他人が書いたコードを読むときなどにちょびっとだけ役立てるのではないかな?

なんて思ったりなんかして。。。