fv17の日記

Webエンジニアの備忘用ブログです。主にWeb界隈の技術に関して書いています。

【各章まとめ】Everyday Rails - RSpecによるRailsテスト入門 - 第1章 イントロダクション

「Everyday Rails - RSpecによるRailsテスト入門 - 第1章 イントロダクション 」の復習用まとめ。

leanpub.com

本書の目的

  • 一貫したテスト戦略を学び、自信を持って開発、機能追加、リファクタリングを行う。
  • テストコードがアプリケーションを守り、変更に対して強くする。
  • 日常的によく使うRSpecの機能と構文を使いこなせるようになる。

なぜRspec

読みやすいから。書きやすいから。

対象となる読者

Rails の開発経験は多少あるものの、テストにはまだ馴染めていない開発者など。テスト駆動開発者らしい考え方を身につけることができる。

筆者が考えるテストの原則

  • テストは信頼できるものであること
  • テストは簡単に書けること
  • テストは簡単に理解できること(今日も将来も)
  • 一番大事なことは テストが存在すること

本書の構成

略。付録にシステムスペックがあるので確認すること。

サンプルアプリに関して

サンプルはプロジェクト管理アプリ。

RSpecを学ぶさらなる情報源

www.betterspecs.org

また、付録にシステムスペックに関する情報あり。

第2章のまとめ

forest-valley17.hatenablog.com

Solidus - Productsまわりの概念まとめ

Solidus、Spreeにおける、Productsに関するまとめ。

SpreeのDevelopers Guideの意訳を元に、SolidusのDevelopers Guideや自分で実装して確認した内容を備忘用にまとめています。

最初にお詫び

手探りで読みながら試しているため、誤った記述の可能性があります。実装する時は公式docを参照してください。本記事は誤った記述があることを前提に日本語でザッと読んでイメージを掴む等に使って頂ければ。

商品(Product)に関連するモデルの概要

Productとは

SolidusにおけるProductとは商品のこと。その商品に関する一般的な情報を保持している。マグカップとTシャツを売ろうとするならば、別々の商品として設定する。

Variantsとは

ある商品の特性のこと。例えば、洋服のS、M、Lなどのサイズや青、白といったカラーのことで、Variantsが異なれば在庫管理を別々に行ったり、異なる価格を付けたりすることができる。1つのProductに対して、複数のVariantsを紐づけることができる。

Option TypeとOption Valueとは

ある商品の特性は、正確にはVariantに紐づいているOption TypeとOption Valueで表現される。例えば、Option Typeが「サイズ」を表し、Option Valueが「M」という具合。1つのVariantに対して、Option TypeとOption Valueの組み合わせは複数紐づけられる場合もあり、例えば、「サイズ」が「M」という1セットと、「カラー」が「青」という1セットが紐づくなど。

Product

Productの属性

  • name : 名前。
  • description : 商品説明。商品ページとかに表示
  • permalink : 商品詳細ページへのURL
  • available_on : ストアで利用可能(買えるよう)になる日付。未設定の場合、表示されないので注意
  • deleted_at : available_onの逆。ストア上で利用できなくなる日付
  • meta_description : サーチエンジン向けの説明。SEO
  • meta_keywords : サーチエンジン向けのキーワード。コンマ区切り。SEO
  • meta_title:HTMLのtitleタグ用。空欄の場合、nameが代用される

Variant

master variant と normal variant の2種類がある

master variant

全ての商品が必ず一つ持ち、商品を新しく作った際に自動で作られる。基本的な情報を保持しており、master variantsに設定されている価格などは、新しくnormal variantが作成された場合に引き継がれる。is_masterプロパティでそのvariantがmaster_variantか確認できる。

normal variants

Option Types と Option Values の組み合わせでユニークになる商品の特性。価格などの設定はmaster variantのものが引き継がれ、こちらで独自に設定した場合は上書きされる。具体例としては、あるTシャツのサイズがSとM、色が白と青ならば下記4通りの組み合わせが考えられる。

  • Sサイズ × 白
  • Sサイズ × 青
  • Mサイズ × 白
  • Mサイズ × 青

Variantの属性

  • weight, height, width, and depth:項目名称のまま
  • cost_currency:原価計算時の貨幣
  • cost_price:製造コスト
  • position:表示順
  • track_inventory:在庫管理するか否か
  • tax_category_id:productのtax categoryを上書き

master variantの取得のコード

Spree::Product.find(1).master
# => <Spree::Variant id: 2, is_master: true, ...>

その他、variants取得時にmasterも欲しい場合は variants_including_master 、不要な場合は variants でアクセス。

Option Types と Option Values

Variantsを理解するためには、option types と option values の理解が必要。
Option Types:商品の特性のこと。例えば、サイズや色。一つの商品に対し、複数設定することができる
Option Values:特性の値。例えば、サイズに対するS・M・L、色に対する白・赤・青

Image

商品の画像。Spree::Imageモデルで管理される。master variantsに全てのvariantsで共通の画像が紐づいており、特性毎に異なる画像の場合はnormal variantsに紐づいでいる。たとえば、自動車の場合、車体の画像はカラーが異なるためnormal variantsに紐付け、車内画像は同一になるためmaster variantsに紐づける。なお、SolidusではPaperclip gem使っており、同一画像を複数サイズで管理している。

Imageの属性

  • viewable_id:その画像に紐づいているvariantのID。なぜvariant_idじゃないのか...謎
  • position:画像が表示される順番
  • alt:alt属性の値。画像の説明
# product(master variant)に紐づく画像をsmallサイズで表示
product.display_image.attachment(:small)

# variantsに紐づく画像を取得
product.variant_images

Product Properties

商品の属性を表し、一商品に対し複数設定することが可能。Variantsと混同しやすいが、こちらは単に商品の付加情報。例えば、ある洋服は異なるサイズ(Variants)を持つが、素材が綿100%であることは共通である場合、その商品のpropertyは「素材:綿100%」となる。

product.property("material")
# => "100% Cotton"

Multi-Currency Support

価格は、貨幣とvariantの組み合わせで決まる。特定の貨幣における、variant毎の価格が存在しない場合、そのvariantはstore上に表示されない。

現在の貨幣でその商品が幾らであるかはpriceメソッドで取得可。

# 商品価格を取得 (master variantの価格を取得)
product.price

# Variants毎の価格を取得
Spree::Variant.find(1).price

貨幣毎の価格を得たい場合には、

Spree::Product.find(1).prices
# => [#<Spree::Price id: 2 ...]
#    [#<Spree::Price id: 3 ...]

Spree::Variant.find(1).prices
# => [#<Spree::Price id: 4 ...]
#    [#<Spree::Price id: 5 ...]

Prototypes

商品が非常に多い場合に、OptionType と Property を商品毎に設定するのは困難。Prototypesでデフォルト設定的なものを作成することができる。

Taxons and Taxonomies

Solidusでは商品をツリー構造(階層構造)のカテゴリーに分けることができる。理解しなければならないのは、Spree::TaxonomysとSpree::Taxonの2つ。

用途に応じて、複数のツリー構造を作ることができるが、その一つ一つのツリーのことをTaxonomyと呼ぶ。デフォルトSeedを投入すると、CategoriesとBrandという2つのTaxonomyが作成されているはず。Taxonは各ツリーのノードのこと。Categoriesが下記のように分かれていたら、その一つ一つの要素がTaxon。

# CategoriesというTaxonomy
Categories
|-- Luggage
|-- Clothing
    |-- T-shirts  # このT-shirtsなど一つ一つのノードをtaxon
    |-- Socks
|-- Shoes

# BrandsというTaxonomy
Brands
|-- Adidas
|-- Bentley
|-- Calvin Klein

階層構造は入れ子集合モデルを元に設計されており、詳しく知りたい場合は下記。また、awesome_nested_set Gemを用いて実装しているため、そちらも参照するとより理解が深まる。

第5回 SQLで木構造を扱う~入れ子集合モデル (1)入れ子集合モデルとは何か :SQLアタマアカデミー|gihyo.jp … 技術評論社
第5回 SQLで木構造を扱う~入れ子集合モデル (2)入れ子集合モデルにおける検索 :SQLアタマアカデミー|gihyo.jp … 技術評論社
第5回 SQLで木構造を扱う~入れ子集合モデル (3)入れ子集合モデルにおける更新 :SQLアタマアカデミー|gihyo.jp … 技術評論社
GitHub - collectiveidea/awesome_nested_set: An awesome replacement for acts_as_nested_set and better_nested_set.

Git - 直前のコミットメッセージを修正する

コミットメッセージを間違えた場合の修正方法

# 間違えた!
git commit -m 'Wrong message!'

修正手順は下記

【方法1】ターミナル上で簡単に修正する方法

git commit --amend -m 'Correct message!'

【方法2】エディタを起動して修正する方法 (エディタがvimの場合)

修正するためにエディタを起動

git commit --amend

編集モードにしてメッセージを修正

エディタ起動状態で「i」をクリックすると、「INSERT」と左下に表示され編集可能な状態になる

保存して完了する

メッセージ編集後、「esc」を押すと編集モードが終了する。その後、「:wq」と入力すると完了。

【Tips】RubyMine上でコミットメッセージを修正したい場合

@jnchito さんが記事を書かれているのでそちらを参照
qiita.com

Rails - DBをリセットし、全データを削除する方法

全データを削除する方法は、下記の2つ

【方法1】全テーブルをdropし、db/schema.rbを元にテーブルを再作成

rails db:reset

db/schema.rbからテーブルを再作成するため、テーブル定義は変わらない

【方法2】全テーブルをdropし、migrationを実行してテーブルを再作成

rails db:migrate:reset

db/migrate/ 以下の全てのマイグレーションファイルを再実行するため、テーブル定義も最新のものになる

jQuery - CSSを操作する方法一覧

CSSのclassを操作

ある要素にCSSのclassを追加

$('要素').addClass('class名')

ある要素からCSSのclassを削除

$('要素').removeClass('class名')

CSSのプロパティを操作

ある要素にCSSのプロパティを追加

$('要素').css('プロパティ名', '値')

複数設定したい場合は、

$('要素').css({'プロパティ':'値', 'プロパティ':'値'});

例えば、

  • 赤文字にする
$('要素').css('color', 'red')
  • 非表示にする
$('要素').css('display', 'none')

jQuery - セレクタ

下記HTMLの各要素を取得、操作することで、jQueryにはどのようなセレクタがあるかをまとめる。

  <p>jQueryのセレクタ</p>
  <ul id="main">
    <li class="item">1</li>
    <li>2
      <ul id="sub">
        <li class="item">2-1</li>
        <li class="item">2-2</li>
      </ul>
    </li>
  </ul>

> 直下の子要素

$('#mail > .item').css('color', 'red')
  • 「1」のみが赤文字になる
  • 「2-1」「2-2」は赤文字にならない

(空白) それ以下の要素

$('#mail .item').css('color', 'red')
  • 「1」「2-1」「2-2」全てが赤文字になる
  • 「2-1」「2-2」だけでなく、それ以下には「1」も含まれる

, 複数の要素

$('p, .item').css('color', 'red')
  • .item要素だけでなく、p要素も赤文字になる

+ 隣接する要素

$('.item + .item').css('color', 'red')
  • .item要素の隣にある.item要素、この場合だと「2-2」のみ赤文字になる

ITエンジニアの効率の良い勉強方法(1) - 遅延評価勉強法

とあるエンジニアの方からアドバイスいただいたのでメモ。

問い

エンジニアはどのように技術を学ぶべきか?
背景は、実務で高いパフォーマンスが出せるよう、適切な対象を高速に学びたい

回答

遅延評価勉強法で学ぶべし

遅延評価勉強法とは?

参考サイト(以下、「参照先」とする)
lukesilvia.hatenablog.com
amachang.hatenablog.com

以下、簡単に自分なりにまとめ

遅延評価勉強法とは

参照先から引用すると

  • その知識が必要になった時に初めて勉強する方法
  • 「○○を学んだから××をやってみる」ではなく、「××をやりたいから○○を勉強する」

上記のようにすることで、遅延評価のように必要な時に、必要な分だけ学習(計算)することになり効率的にキャッチアップできる。

遅延評価勉強法のメリット

やりたい駆動、あるいはやらなきゃいけない駆動での学習となるため、

  • 勉強へのモチベーションが高い
  • 必然的に学んだことをすぐにアウトプットするため、学習効果が高い

一方で、何だか良くわからないけど本に書いてあるから学ぶという状態だと、なぜ学ぶのか?、これを学ぶ意味はあるのか?、学んでもツマラナイ...となりがちで、

  • 勉強へのモチベーションが低い
  • 面白くないので、勉強が続かない、覚えてもすぐ忘れる
  • 意識しないとアウトプットせずに終わるため、体験的な学習ができず費用対効果が著しく低い

自分の勉強方法で見直すところ、チェックポイント

  • そもそも何を目的に学ぶかを明確にする
  • その目的や目標を達成するために、具体的に何を学ぶべきかを明確にする
  • その学ぶ対象を獲得するために、最小の労力で学ぶためにはどうするべきかを考える
  • その学ぶ対象を獲得するために、今学んでいることは本当に必要か?を自問する

特に、今やっていることは本当に必要か?という視点は常に持ちたい。

分厚い書籍とかは最初から全部読んでく方式よりも、必要な部分だけを都度読むスタイルの方が絶対良い。個人的には、

  • 入門書は全部サラッと読んで、特に必要な部分を重点的に復習・参照
  • 中級以上の本だと、全部読まずに必要な個所だけ読む

とは言っても書籍によっては、最初の章から順繰りで読んでかないと後半の章は意味不明とかもあるので臨機応変に。

より体験的な学習をして学習効率を高めるための工夫

個人的には、写経するだけの教材の場合、それだけだと全く身につかない。要はインプットしているだけの状態だと、やった気にはなるが身に付かない状態となるため、下記を意識している。

  • 演習問題解く
  • 自分でサンプル作る
  • 別途開発中の製品に組み込む
  • 特に必要なさそうだと感じた部分については思い切って読み飛ばす
  • 一旦インプットしたら、重要な部分のみ抽出してブログに書き起こしてみる