WordPressから、はてなブログへの移行について(+Markdown記法に戻す)
- なぜ、はてなブログへ戻したか?
- 参考:WordPressブログのダメなところ
- 前準備
- WordPressからエクスポート
- はてなブログへインポート
- タグがカテゴリー化するので、不要ならば除去する
- ブログ内のリンクを貼り直す
- WordPressのブロック記法が残っていたので、Markdown記述に戻す
- 最後に
なぜ、はてなブログへ戻したか?
まあ、多くの方と同様に経済的な理由です。
知人らのアドバイスなどをもとに、個人サイト立ち上げるきっかけとして、まずは、アフィリエイト付きのオリジナルドメイン+WordPressブログをはじめましたが、割に合わないので停止しました。
仮に月1,000円+プラスドメイン料金だとすると、年間12,000円以上はかかりますよね。
ドメイン料金も払いたくないので停止し、はてはも無料プランのままとしました。
つまり、https://inuinu-tech.hatenablog.jp/entry/〜といったURLのままとしています。
参考:WordPressブログのダメなところ
WordPress(+アフィリエイト)ブログのハードルの高さについて
WordPressについては、ざっとこんな感じでしょうか。
- サーバー選定やWordPressデザインテーマを選択するだけで、かなりの時間と精神を消耗する
- WordPressの導入や初期設定で、相当な時間を費やす
- SEO対策について、相当な時間を費やす
- 固定ページ作成に時間を費やす
- カテゴリやタグの体系づくりで時間を費やす
- ブロックエディタ特有の冗長な文字列の塊が、Markdown使いには耐えられない
さらに、多分に切っても切れないアフィリエイトについても書き加えます。
サーバー選定やWordPressデザインテーマを探す場合、ほぼ100%アフィリエイトブログにぶち当たります。
当然ながら、アフィリエイターにとって都合のいい話しか書いていません。
あまり参考にならないと思います。
これをクリアするには、有名そうなブログが何を使っているかを見るといいかもしれません。
ネットを探すと、ドメインからサーバーを検索し、さらにWordPressテーマも教えてくれるページがあったと思いますので、試してみて、それに倣う方が良いかもしれません。
あとは、某掲示板の書き込みなども参考になるかと思います。
その後、晴れて加入〜導入〜設定に移りますが、これもノウハウの収集を含め、かなりの時間を費やします。
特に注意したいのはプラグインで、ネットで見た「おすすめプラグイン」が既に時代遅れなんてことがよくあります。
また、多くのプラグインは徐々に肥大化して有料化したり、他のプラグインとバッティングする運命をたどります。
今人気のデザインテーマを導入⇒そのデザインテーマサイトがおすすめするプラグインを最低限入れてみる…という流れが賢明かと思います。
固定ページとは、自己紹介、免責事項、問い合わせフォームなどです。
問い合わせフォームはプラグインを利用しますが、その他は自分で作成する必要があります。
アフィリエイターも、ある種の個人商店みたいなものですから、下手なことは書けません。ここでプロの洗礼を受けるかと思います。
同時に自分が書きたいことの大系を考えて、カテゴリ(場合によってはディレクトリあるいはサブドメイン)を考える必要があります。
さらにアフィリエイト業者、アドセンス広告や、物販アフィリエイト、その他のアフィリエイト業者への登録が必須になると思いますが、年々厳しくなっていると思います。
さらに、アフィリエイトブログを書く場合、自分の経験に基づいた記事を書くのがセオリーですが、自分の経験が例えば「病気からの回復」だとして、それが例えば「お世話になった医療保険」とかに紐づくと、YMYLに引っかかる可能性が高まります。
私はやっていませんでしたが、DIYモノは多分行けると思いますが、これが業者にお願いするリフォームとかになると、難易度が上がるかも。
さらに、経験から「中古一戸建て・マンションの賢い買い方」となると、まあ、厳しいかもしれませんね。
ですので、B級グルメブログとか旅行記とか、家電使用記とか、そういった無難な方向に行きがちかもしれませんね。
ただライバルが多いですし、仕入れというか、売上原価が発生して旨味はほとんどなさそうですし、また、動画で配信できれば、ブログにこだわる必要もないですしね。
さらに、コツや経験をつかみつつ、どのコンテンツが当たるか?自分が記事を豊富に用意できるか?となると、相当な時間を費やすのでは?と思います。
言い方悪いですが、仕事で忙しい人には無理だと思います。
以上、こういったことのうち、いくつかが、「入門書」に書かれていますが、多分に読むだけで嫌になってしまうと思います。
私はエンジニアで、WordPress導入について興味があったので、上記を試しましたが、まあ、大変でしたね。
経験で得たものは沢山ありました(固定ページ作成は特に)。が、素人では手が出ないと思います。
物販アフィリエイトで小遣いを稼ぐならば、無料ブログで十分かと
多くの場合は、日常や趣味の延長でブログをかくと思いますので、そのついでに商品紹介でお小遣いを稼ぎたいのであれば、無料ブログで十分かと思います。
前準備
前置きが長くなりましたが、変換作業を始めていきます。
各エントリをブラウザで保存する
私の場合は、ドメイン及びサーバーの停止期限が迫っていたのと、100件程度のエントリしかなかったので、各エントリをブラウザで保存しました。
画像等でいくつか壊れた箇所がありましたが、それ以外は無事保存はできました。
これで、スタンドアロンで旧ブログのレイアウトを含めた内容が把握できます。
この保存したページは、後で、インポート後との比較(間違い探し?)をする際に使用しますが、次の点で特に役に立ちました。
ちょっと、億劫な作業ですが、やっておいた方が良いです。
WordPressからエクスポート
「ツール>エクスポート」でエクスポートします。
個人的には「投稿」で行いましたが「すべてのコンテンツ」でも大丈夫だと思います。
はてなブログへインポート
Markdownモードにしておく(任意)
私は、普段からMarkdownで記述していましたので、Markdownモードにしておきます。
インポートする
管理画面からインポートしてください。
100件程度でしたら、わりとすぐに終わります。
エントリとURLを確認
各エントリがインポートされているか、確認してください。
さらに、URLが、WordPress推奨の形でインポートされているかも確認してください。
(私はこちらは無問題でした。)
タグがカテゴリー化するので、不要ならば除去する
多分に、最初に???と思う箇所はこれです。
不要なタグがあれば除去しますが、エントリも多いですし、殆どの場合は放置かと思います。
ブログ内のリンクを貼り直す
私はプログラミングテクニックのハウツーでしたので、内部リンクが多数ありましたが、こちらは表に表示されず、さらに古いURLのままです。
これを、根気よく「はてな記法」にて貼り直していきます。
URLをペーストすれば、アシスタント画面が表示されますので、そちらに従います。
WordPressのブロック記法が残っていたので、Markdown記述に戻す
こちらの作業が思いの外かかりました。
WordPressでは今流行り?のブロックエディタを使用していたので、中を見ると、それがそのまま残っています。
このままでは文字数が無駄に多くなってしまうので、ともかく、なんとかしたいところ。
修正しながら、CSSを手直ししていく
参考までに、こちらのブログのデザインテーマは、デフォルトの「Life」になります。
CSSでカスタマイズを行っています。
主な内容は、
- タイトルおよびエントリータイトルの大きさ調整
- 目次のカスタマイズ
- h2/h3/h4を目立つように、さらに前後の間隔を開ける
- strongをアンダーライン化
- preタグの色を白黒反転
- WordPressによくあるボックス表示の追加
こんなところでしょうか。
あまり凝らないように心がけます。
pタグ/brタグ
●変更前
<!-- wp:paragraph --> <p>1行目です。<br>2行目です。</p> <!-- /wp:paragraph --> <!-- wp:paragraph --> <p>3行目です。</p> <!-- /wp:paragraph -->
●変更後
1行目です。 2行目です。 3行目です。
「1行目です。」の直後に2文字の半角スペースを挿入します。
これでbrタグの代わりになります。
これだけでも、相当スッキリします。
h2/h3/h4タグ
こちらも冗長化していますので、なんとかします。
●変更前
<!-- wp:heading --> <h2 class="wp-block-heading">これが</h2> <!-- /wp:heading -->
●変更後
## こうなる
h3の場合は###とします。
ul/olタグ
●変更前
<!-- wp:list {"className":"hoge"} -->
<ul class="foo><!-- wp:list-item -->
<li>やること1</li>
<!-- /wp:list-item -->
<!-- wp:list-item -->
<li>やること2</li>
<!-- /wp:list-item -->
<!-- /wp:list -->
●変更後(ulタグ)
* やること1 * やること2
olタグの場合は、
1. やること1 1. やること2
となります。
これはかなり文字数が圧縮できますね。
アンダーライン
WordPress系のブログを見ていると、アンダーラインをよく見かけますよね。
こちらはWordPressの機能というよりも、テーマの機能でしょうか。
こちらをstrongに変更し、CSSでアンダーラインをつけるようにします。
CSSは「管理画面>デザイン>カスタマイズ(スパナのアイコン)>{}デザインCSSのボックス内をクリック」で、エディタ(のようなもの)が開きますので、そこに記述します。
●変更前(SWELLの例)
<span class="swl-marker mark_yellow">この箇所にはアンダーラインが付きます</span>
●変更後(本文)
**この箇所にはアンダーラインが付きます**
●変更後(CSS)
.entry-content strong { font-weight: normal; background: linear-gradient(transparent 50%, yellow 50%); }
上記例はstrongでの例ですが、emタグ(*〜*)で対処したい方は、上記を応用してみてください。
WordPressテーマが用意したボックス類
私はWordPressの人気テーマ「SWELL」を使用していましたが、その他のテーマにも、見栄えを良くするオプションが多数用意されています。
代表的なものは「吹き出し」ですが、私が扱う内容はプログラミングテクニックなので、幸い無使用でした。
ただし、ボックス類はいくつか使用していました。
上記リンクで言うところの「アイコン付きボックス(小)」と「アイコン付きボックス(大)」ですね。
こちらを置き換えていきますが、こちらはMarkdownでも「はてなブログ」でも用意されていませんでしたので、以下のようにしました。
この記事に登場する「!」の例になります。
●変更後(本文)
<fieldset class="kakomi_alert"><legend class="kakomi_alert"></legend> 注意点を記述します。 </fieldset>
●変更後(CSS)
/* 共通 */ fieldset { margin-bottom: 3em; padding: 0px 20px 20px 20px; border: 2px solid; border-radius: 10px; -moz-border-radius: 10px; -webkit-border-radius: 10px; } fieldset ::before { margin-left: 10px; margin-right: 10px; font-family:blogicon; font-size:35px; } /* 警告 */ fieldset.kakomi_alert { border-color: gold; } fieldset .kakomi_alert::before { content:"\f041"; /* blogicon-warning */ color: gold; }
変更箇所が結構な数あったため、
- そもそも、ボックスで囲む必要が本当にあるのか?
- ボックス内の文章は適切か?
というチェックを行い、不要な文章、例えばフランクな表現や、独り言のようなものは、極力削除することにし、ボックスの数を減らしました。
参考までに、以下のボックスに絞っています。
チェックアイコン:記事や章の要約、リンク先の説明
/* チェック */ fieldset.kakomi_check { border-color: limegreen; } fieldset .kakomi_check::before { content:"\f029"; /* blogicon-check */ color: limegreen; }
メモアイコン:備考、これを行う意味など
/* メモ */ fieldset.kakomi_memo { border-color: orange; } fieldset .kakomi_memo::before { content:"\f024"; /* blogicon-pen */ color: orange; }
はてなアイコン:質問
/* はてな */ fieldset.kakomi_hatena { border-color: fuchsia; } fieldset .kakomi_hatena::before { content:"\f01c"; /* blogicon-help */ color: fuchsia; }
警告アイコン:これを行うとリスクがあることを警告
/* 警告 */ fieldset.kakomi_alert { border-color: gold; } fieldset .kakomi_alert::before { content:"\f041"; /* blogicon-warning */ color: gold; }
禁止アイコン:これは不可能、あるいは禁止
/* 禁止 */ fieldset.kakomi_stop { border-color: red; } fieldset .kakomi_stop::before { content:"\f025"; /* blogicon-close */ color: red; }
preタグにもどす
私はWordPressのテーマはSWELLを使用しており、その作者が作成したと思しき、「Highlighting Code Block」というプラグインを利用しておりましたが、こちらは一般的なpreよりも、以下の利点がありました。
- 行番号の表示
- プログラム名の表示
- コピーボタン押下でソースコードがコピーできる
- プログラムごとにカラー表示
反面、以下の欠点があります。
- preタグではない(div+codeタグ)
- 記号は
&といった参照文字に変換されてしまう
はてなブログでも```言語名でカラーリングをしてくれますが、「Highlighting Code Block」での記述箇所はインポートで変換してくれませんので、カラーリングはしてくれません。
なので、この変更は、私的には必須としました。
●変更前
<!-- wp:loos-hcb/code-block {"langType":"js","langName":"JavaScript","fileName":"hoge.js"} -->
<div class="hcb_wrap"><pre class="prism undefined-numbers lang-js" data-lang="JavaScript"><code>if (strStatus == '1') {
処理1
} else if (strStatus == '2') {
処理2
}</code></pre></div>
<!-- /wp:loos-hcb/code-block -->
●変更後(```の直後にjavascriptを付加)
if (strStatus == '1') { 処理1 } else if (strStatus == '2') { 処理2 }
&で始まる実体参照はとてもじゃないけど手作業で変換はできませんので、「前準備>各エントリを保存する」で保存したページをブラウザで表示し、コピペしました。
(運良く、コピーボタンが生きていたので助かりました。)
テーブル
●表示例
| タグ | 発火点 | 取得方法 |
|---|---|---|
| SELECT | onchange() | elm.value |
| INPUT(radio) | onclick() | elm.value |
| INPUT(checkbox) | onclick() | elm.forEach(function (el) ⇒el.checkedを確認(true or false) |
●変更前
<!-- wp:table --> <figure class="wp-block-table"><table><thead><tr><th>タグ</th><th>発火点</th><th>取得方法</th></tr></thead><tbody><tr><td>SELECT</td><td>onchange()</td><td>elm.value</td></tr><tr><td>INPUT(radio)</td><td>onclick()</td><td>elm.value</td></tr><tr><td>INPUT(checkbox)</td><td>onclick()</td><td>elm.forEach(function (el)<br>⇒el.checkedを確認(true or false)</td></tr></tbody></table></figure> <!-- /wp:table -->
●変更後
|タグ|発火点|取得方法| |:---|:---|:---| |SELECT|onchange()|elm.value| |INPUT(radio)|onclick()|elm.value| |INPUT(checkbox)|onclick()|elm.forEach(function (el)<br>⇒el.checkedを確認(true or false)|
こちらは画面とにらめっこしないと変換できないかも…
面倒でしたら、スルーしてもいいかもしれません。
codeタグ(インラインのcode)
●変更前
<code>hoge</code>
●変更後
`hoge`
こちらは、そのままにしてもいい気がします。
最後に
以上となります。
修正することで、文字数が半分以下に圧縮できると思います。
また、意外と、誤字脱字や説明不足等を見つける、良い機会となりました。
【Ruby on Rails7】バリデーションだけではなくスキーマも連携させる
- バリデーションとスキーマの属性は一致させておく
- null: falseと, default: ""とpresence: true
- unique: trueとuniqueness: true
- limit: nとmaximum: n
- stringとnumericality: true
バリデーションとスキーマの属性は一致させておく
バリデーションだけではなく、実際のテーブルも合わせておくことが望ましいです。
以降は、実際のシステムに近い例示をしつつ、記入例を紹介していきます。
null: falseと, default: ""とpresence: true
Railsではキーや更新日次など主要な項目以外、NULL抑制やデフォルト値は設定されないのですが、多くのDBでは、NULL抑制やデフォルト値を持つことを推奨されます。
以下はマイグレーションの例です。
add_index :customers, :fax_no, unique: true
この例では、デフォルト値が入るので、バリデーションは不要かと思いますが、もし、入力必須を伴う場合は、モデルは以下となります。
validates :fax_no, presence: true
FAXってまだ使うの?
複合機くらいはあるでしょ?的な議論はさておき、入力必須にしている入力フォームは見かけなくなりましたね。
unique: trueとuniqueness: true
Railsの場合はidというプライマリーキーがデフォルトで付加されます。
しかし、顧客コードや商品コード、社員番号、支店コードなど、idの他に基幹システムのマスターコードを持ちたいというニーズはあると思います。
その場合の、マイグレーションはこうなります。
(例は、ユーザーテーブルに社員番号を持ちたいといったケース。)
add_index :users, :shain_cd, unique: true change_column :users, :shain_cd , :string, limit: 10, null: false, default: ''
モデルはこうなります。
validates :shain_cd, presence: true, uniqueness: true
ユニークキーを作成するとともに、バリデーションでuniqueness: trueを追加します。
これで社員番号の一意性が確保されます。
可能な限り、コード値の場合は有効桁数を設定しましょう(基幹システムと合わせることが望ましい)。
NULLも抑制し、default: ''も付加します。
limit: nとmaximum: n
maximum: nのみ
マイグレーションはこうなります。
change_column :tables, :short_name , :string, limit: 10
モデルはこうなります。
validates :short_name, length: { maximum: 10 }
上記は0文字〜10文字入力可能ですが、入力必須の場合はminimum: 1をつけるか、presence: trueをつけるか、どちらかになります。
(エラーは排他的なので2行になることはありませんが、1文字以上10文字以下というメッセージが、好ましいか悩むところですね。)
minimum: nとmaximum: n
例えば2文字のみ有効としたい場合、マイグレーションはこうなります。
change_column :tables, :category , :string, limit: 2, null: false
モデルはこうなります。
validates :category, length: { minimum: 2, maximum: 2 }
minimum: nとmaximum: nを指定した場合、必ず2文字入力しないといけなくなるので、presence: trueが余計になると思います。
(あっても構いませんが、エラーメッセージが2行表示されて、ちょっとうるさい印象です。)
stringとnumericality: true
こちらは、(桁数制限以外の)マイグレーションは必要ありません。
文字列カラムなのですが、入力値は数値のみというケースがあると思います。
その場合のモデルのバリデーションは以下となります。
validates :flg, numericality: true, length: { minimum: 1, maximum: 1 }
上記例では1桁の数値のみが入力可能です。
【Ruby on Rails7】RSpecおよびshoulda-matchersのインストール
RSpecおよびshoulda-matchersの導入
Gemfileに追記しインストール
まずはGemfileに追記します。
group :development do gem "rspec-rails" end gem "shoulda-matchers"
コマンドラインで、インストールします。
bundle install
さらに、RSpecをインストールします。
bundle exec rails g rspec:install
shoulda-matchersの設定
spec/rails_helper.rbの最後に、
Shoulda::Matchers.configure do |config| config.integrate do |with| with.test_framework :rspec with.library :rails end end
を追記します。
使用方法
モデルにRSpecテストプログラムを導入
以下のコマンド実行します。
(Userはモデル名の例。)
bundle exec rails g rspec:model User
次に、spec/models/user_spec.rbの、
pending 'add some examples to (or delete) #{__FILE__}';
を削除します。
shoulda-matchersの一例
先ほど変更したspec/models/user_spec.rbに追記します。
it { is_expected.to validate_presence_of :shain_no }
it { should have_db_index(:shain_no).unique }
上記はshoulda-matchersのの記法例です。RSpecでは一つのエラーを実現するだけでも、(ダミーデータを作成するなど)数行かかるのですが、1行で済みます。
テーブルusersには、shain_noがあり、idの他にこの項目でもユニークになっていないといけないとします。
当然ながら入力必須です。
もし、モデルuserに何もせってせず、このまま、下記のコマンドを実行すると、
bundle exec rspec spec/models/user_spec.rb -f d
2件エラーになるはずです。
そこでバリデーションを、app/models/user.rbに追記します。
validates :shain_no, presence: true, uniqueness: true
下記のコマンドを実行すると、
bundle exec rspec spec/models/user_spec.rb -f d
エラーはなくなり、さきほどの2件は成功となるはずです。
shoulda-matchersのできること、できないこと
shoulda-matchersについて
shoulda-matchersはモデル用の省略記法のようですので、単純なエラーの記述の冗長化を防ぐことができます。
RSpecは単純なエラーでも数行かかるので、そうではないエラーとの見分けがつくのは助かります。
こちらを参考にさせていただきました。ありがとうございます。
本家サイト。
下部に使用できるテスト内容が書いていますが、かなり豊富に用意されていますね。
【Ruby on Rails7】SELECT/OPTIONタグ用のテーブルを作成
テーブル構造を考える
他の(マシンの)システムで多いのは、コードテーブル、名称テーブルの類を利用する
一般論として、顧客マスターや商品マスター、社員マスターといったマスターでは、顧客マスターや商品コード、社員番号といったユニークキー(プライマリーキー)と、顧客名、商品名、社員名といった名称、さらに住所や販売価格、在庫数といった付随する情報がセットされていると思います。
どんなシステムでもコード値の存在チェックは行いますので、それを利用して、名称を表示しています。
そういったマスター以外に、細かい区分やフラグといったものに名称をつけたいといったニーズがあり(例えば、商品でしたら、1=仕入商品、2=委託商品など)、一般的には、これを名称テーブルあるいはコードテーブルといったファイル名で取り扱うケースが多々あります。
もし、これがすでに基幹システムなどに存在し、夜間バッチ等でRails用のデータベースに差し替えるようなことが可能ならば、それを利用してSELECTのOPTIONタグの表示名称として利用したいのですよね。
コードテーブルのデータ構造について
多くのケースでは、
- コードヘッダー:コードキー(ユニークキー)と、このコードの名称や使用目的等を記述
- コード明細:コードキー(ユニークキー)と実際の区分値とその名称や略称を保持
といった親子関係で表現されていることが多いと思います。
画面に表示される桁数には制限があるので、多くの場合は略称を持っています。
Ruby on Rails(Activerecord)の制限をもとにしたテーブル構成
もし、Railsでこれをインポートするには、以下の構造になるはずです。
- コードヘッダー:idとコードキー(ユニークキー)と、このコードの名称や使用目的等を記述
- コード明細:*idと、ヘッダーテーブルのid**、実際の区分値とその名称や略称を保持
Railsのプライマリーキーはidになりますので、子にはヘッダーテーブルのidを持つことで、親子関係を実現します。
こちらをもとにして実装していくことにします。
(参考)夜間バッチで差し替えるには?
参考までに、ロジックを考えてみます。
プログラムその1:コードキー(ユニークキー)が期間。Rails両者に存在する場合
親テーブルをUPDATEし、子のテーブルをDELETE/INSERTします。
その際、親のidを子にセットします。
プログラムその2:コードキー(ユニークキー)がRails側に存在しない場合
親テーブルをINSERTし、子のテーブルをINSERTします。
親テーブルのidは新規に与えられますので、コードキー(ユニークキー)で親のidにを取得し、その親idも含めた形で子をINSERTしてください。
プログラムその3:コードキー(ユニークキー)がRails側にのみ存在する場合
基幹側が削除されたとみなし、親テーブルをDELETEし、子のテーブルもDELETEします。
実装手順
親子のテーブル作成
まずは親のテーブルを作成します。
bundle exec rails g scaffold Codeheader code_key:string code_name:string
code_keyは基幹システムのプライマリーキー、code_nameはこのコード自体の名称を記述します。
のちほど、cocoonでメンテナンス画面を作成するために、g scaffoldにしておきます。
次に、このテーブルを作成します。
bundle exec rails g model Codedetail value_key:string value_name:string short_name:string codeheader:belongs_to
value_keyは区分やフラグの値、value_nameはその名称、short_nameはその略称です。
codeheader:belongs_toで親テーブルのidをセットするカラムが作成されます(MySQLではid同様bigintとなる)。
こちらはscaffoldではなくg modelにしておきます。
モデルに追記する
app/models/codeheader.rbに以下を追記します。
has_many :codedetails, dependent: :destroy #accepts_nested_attributes_for :codedetails, reject_if: :all_blank, allow_destroy: true accepts_nested_attributes_for :codedetails, allow_destroy: true
reject_if: :all_blankは親のみ作成される危険性があるため、記述を除去します。
app/models/codedetail.rbに以下を追記します。
belongs_to :codeheader
ヘルパーにSELECT/OPTION用の配列を求める関数を作成
app/helpers/application_helper.rbに以下を追記します。
# select/optionを取得 def get_select_option(key) return Codedetail.joins(:codeheader).select("codeheaders.*, codedetails.*").where("codeheaders.code_key = ?",key) end
ビュー側でヘルパーの関数を埋め込む
_form.html.hamlに以下を追記します(追記例)。
.field.col-md-4.mb-3 = f.label :category, class: "form-label" = f.collection_select :category, get_select_option('category'), :value_key, :value_name, {prompt: "選択してください"}, :class => 'form-control', :id => 'category'
上記はcategoryというコードキーを持つ一覧を取得してOPTIONタグを生成していきます。
value_nameをshort_nameに変更すると、略称がセットされると思います。
かなり簡単に実装できましたね。
cocoonを使って、メンテンス画面を作成する
基幹からデータ持ってくるだけでしたら、別段必要はないですが、基幹もなく、イチから用意したい場合は、cocoonを利用した管理画面を用意したほうが良いかと思います。
幸い、cocoonについてのコラムは用意していますが、それをリンクしながら、異なる点などを説明します。
cocoonのインストール
「modelおよびscaffoldの作成」はこの記事のものを使用してください。
それ以降もProject、project、projectsはCodeheader、codeheader、codeheadersに差し替えてください。
同様に、Task、task、tsaksはCodedetail、codedetail、codedetailsに差し替えてください。
「コントローラーの変更」のパラメータは下記のように変更してください。
●app/helpers/application_helper.rb
# Only allow a list of trusted parameters through. def codeheader_params #params.require(:codeheader).permit(:code_key, :code_name) params.require(:codeheader).permit(:code_key, :code_name, codedetails_attributes: [:id, :value_key, :value_name, :short_name, :_destroy]) end
cocoonのエラー訂正
tasksはcodedetailsに差し替えます。
Task、task、tsaksはCodedetail、codedetail、codedetailsに差し替えてください。
子の二重登録エラーは、前出のapp/helpers/application_helper.rbのパラメータ変更が行われているのならば、発生しないはずです。
子の0行エラー抑制
Project、project、projectsはCodeheader、codeheader、codeheadersに差し替えてください。
同様に、Task、task、tsaksはCodedetail、codedetail、codedetailsに差し替えてください。
子の件数抑制
Project、project、projectsはCodeheader、codeheader、codeheadersに差し替えてください。
同様に、Task、task、tsaksはCodedetail、codedetail、codedetailsに差し替えてください。
(taskはTASKもありますね。)
行コピー
taskのみcodedetailに読み替えてください。
子の重複チェック
projectをcodeheaderに差し替えてください。
同様に、tsaksはcodedetailsに差し替えてください。
以上で、cocoon化は完了するかと思います。
お好みで
お好みで、ページネーションや検索、ソートを実装してみてください。
時間があれば、日本語化も。
これで、ほぼほぼ良い感じになると思います。
【Ruby on Rails7】Rails7を導入する
バージョン3.0以上のRubyを導入する
Rails7での推奨バージョンを確認する
とあるので、最新バージョンに近いバーションをrbenvを通じてインストールします。
結果3.2.2をインストールしました。
バージョン7.0以上のRubyを導入する
共通のgemエリアにインストールしたくない場合はどうするか?
下記サイトが参考になりました。ありがとうございます!
こちらのサイトの手順に近い方法でインストールしていきます。
ベースディレクトリを作成し、一時ディレクトリ(.bundle)内インストールする
まず、ベースとなるフォルダを作成します。
(このフォルダはプロジェクト名ではないことに注意してください。)
以下のコマンドを実行します。
bundle init
作成されたGemfileを変更します。
gem "rails", '=7.0.8'
7.0.8は執筆段階での最新バージョンになります。
(こちらは適宜変更してください。)
以下のコマンドを実行します。
bundle install --path .bundle/
これで、.bundleというフォルダにRailsその他がインストールされます。
バンドル無しで、Railsのプロジェクトを開始する
以下のコマンドを実行してください。
SQLiteを使用する場合、
bundle exec rails new プロジェクト名 --skip-bundle
MySQLを使用する場合(事前にインストールする必要があります)、
bundle exec rails new プロジェクト名 -d mysql --skip-bundle
Gemfileだけを作成するようなイメージでしょうか。
Gemfileを追記する
プロジェクト名フォルダ内に作られたGemfileに必要なものを追記していきます。
一例として私の評価用のプロジェクトを上げておきます。
●Gemfile
# Bootstrap5 gem "bootstrap", "~> 5.2.0" gem "mini_racer", "~> 0.6.2" # テストプログラム group :development do gem 'rspec-rails' end # テストプログラム(簡易書式化) gem "shoulda-matchers" # haml gem 'haml-rails' # 日本語化 gem "rails-i18n", "~> 7.0.0" # ページネーション gem "kaminari" gem 'bootstrap5-kaminari-views' # 検索機能 gem "ransack" # cocoon gem 'cocoon'
Bootstrap5については、gem以外にもいくつかの手順があります。下記を参照してください。
テストプログラムでRSpecを使用したい場合は追記します。
shoulda-matchersは、RSpecの簡略記法となります。
hamlはgemのみでインストールは完結しますが、導入時点では、Rilas7でのレイアウトがerbとは異なっています。
詳細はこちらを参考にしてください。
国際化パッケージ(=日本語化パッケージ)のi18nは、gemインストール以後も導入作業があります。下記を参照してください。
ページネーションおよび検索機能(ソート機能含む)については、下記をご参照ください。
(両者は相性がいいので一括して導入したいということもあるかと思います。)
親子関係にあるテーブルを一括で入力する場合、明細追加や削除等のアクションを簡略化できるパッケージcocoonの導入および問題解決、関連する機能の追加については、下記のコラムシリーズをチェックしてみてください(関連するコラムは10以上あります)。
ベースフォルダのgemを削除する
次に、ベースフォルダー直下にある.bundleフォルダとGemfileを削除します。
プロジェクト内のgemをvender内にインストールする
以下のコマンドを実行してください。
bundle install --path vendor/bundle/
(MySQLのみ)データベースを作成する
SQLiteの場合は、すでにデータベースファイルが作成されていると思いますが、MySQLの場合はデータベースに接続するためconfig/database.ymlを変更します。
password: (パスワードを入力)
さらに、以下のコマンドを実行します。
rake db:create
MySQL Workbench等のユーティリティソフトで、データベースの作成を確認してください。
プロジェクト名_developmentとプロジェクト名testの2つのデータベースが作成されているはずです。
動作確認
以下のコマンド実行してください。
bundle exec rails s
さらに、下記のURLをクリックしてください。
Railsのトップページが表示されたら、動作確認の完了です!
【Ruby on Rails7】Rails7にBootstrap5をNode.jsなしで導入する
- 導入時の環境について
- 導入手順
- 動作確認用のページを作成する
- mini_racerについて
- 動作確認後Bootstrapを拡張したデザインテンプレートを導入するには?
- JQueryベースのBootstrapを使用し続ける場合
- 他の選択肢はないのか?
導入時の環境について
導入時の環境
導入時の環境は以下の通り。
前提条件としてNode.jsをインストールしていないこと
これは重要な点ですが、Node.jsをインストールしていないことが前提条件になります。
もし、すでにNode.jsを導入済みの場合で、アンインストールできない場合は、導入していないマシンを選択する等を行ってください。
導入手順
emfileに追記しインストール
まずはGemfileにBootstrapを追加します。
# Bootstrap5 gem "bootstrap", "~> 5.2.0" # please switch to Node.js (V8) or mini_racer (V8)が出た場合 gem "mini_racer", "~> 0.6.2"
思い切って最新版を入れちゃいましょう。
mini_racerについては、後ほど説明します。
さらに、
bundle install
でインストールします。
importmapのインストール
binディレクトリにimportmapがない場合は、下記コマンドを実行します。
bundle exec rails importmap:install
bin/importmapおよびconfig/importmap.rbが作成されます。
さらに、以下のコマンドを実行します。
bin/importmap pin bootstrap
Javascriptファイルの変更
app/javascript/application.jsに下記を追記します。
import 'bootstrap'
cssをscssに変更
まず、app/assets/stylesheets/application.cssの名前をaplication.scssに変更します。
その、app/assets/stylesheets/application.scssの中身を(すでにカスタマイズしていない場合)全て消して、以下を追記します。
@import "bootstrap";
設定は以上となります。
動作確認用のページを作成する
どこに何を作成するか?
動作確認については、Bootstrap+Javascriptですと、プルダウンメニューの例が良いと思います。<
メニューバー等が用意されていない場合は、下記参考サイトのビューを適当に移植してみてください。
プルダウンメニュー(dropdown)が動作していれば、Javascript含め、問題なくインストールされています。
mini_racerについて
Node.jsまたはmini_racerが導入されていないと、Railsがエラーを吐き出す
もし、Node.jsまたはmini_racerが導入されていないと、Railsがエラーを表示します。
please switch to Node.js (V8) or mini_racer (V8)
V8エンジンが必要だというエラーメッセージですが、どうやら、動作確認をNode.jsとmini_racerで行っているようです。
ここが、mini_racerをインストールする理由になっています。
環境によってインストールできるバージョンが違う(っぽい)
私の環境(Intel Mac)だけかもしれませんが、最新版のmini_racerでは動作しませんでした。
ですので、意図的にバージョンを下げています。
動作確認後Bootstrapを拡張したデザインテンプレートを導入するには?
CDNがあれば、importmapのpinを変更する
config/importmap.rbのpin以降のURLを変更します。
# config/importmap.rb pin "bootstrap", to: "CDNのURL"
あるいは、Javascriptファイルをダウンロードして、サーバー内のパスを指定しても良いかと思います。
importmapはJavascriptのみ、CSSはどうするか?
ダウンロードし、app/assets/stylesheetsディレクトリに起きます。
さらに、app/assets/stylesheets/application.scssを変更します。
(下記はbootstrap.min.cssの場合。)
#@import "bootstrap"; @import 'bootstrap.min';
JQueryベースのBootstrapを使用し続ける場合
無理にBootstrapのバージョンを上げずに、別途JQueryをいれてしまったほうが良い
動作が安定しているのであれば、クライアントからデザイン変更等のリクエストがない限り、無理に変える必要は無いのでは?と思います。
以下に、Rails7での導入例を説明いたします。
まず、下記のコマンドを実行します。
bin/importmap pin jquery
config/importmap.rbを確認し、挿入されていない場合は、追記してください。
# config/importmap.rb pin "jquery", to: "https://ga.jspm.io/npm:jquery@3.7.1/dist/jquery.js"
上記のJQueryのが新しすぎるのであれば、適当に変更したほうが良いかと思います。
さらに、app/javascript/application.jsの中を確認し、下記の行がない場合は、追記してください。
// app/javascript/application.js import jquery from "jquery" window.$ = jquery
他の選択肢はないのか?
CDNあるいはダウンロードしたファイルでBootstrapを導入したほうが楽?
調べたところ、CDNを直接app/views/layout/application.html.erbに書く手法もあるようですね。
gem経由で受けられる恩恵もあるかと思いますので、kaminari用のbootstrapが動作するかは確認したほうが良いかもしれません。
こちらでも、プルダウンメニューが動作するのであれば、mini_racerの出番はないかもしれませんね。<
Node.jsレスあるいはJavascriptレスのCSSを採用したほうが楽?
Node.jsレスあるいはJavascriptレスのCSSを採用するという手法もあります。
TailwindCSSですとか、Yahoo!が開発したPure.cssもそうだったと思います。
【Ruby on Rails7】Rails7にi18nを導入する
i18nとは?
i18nは正式には国際化ライブラリーの総称です。
フルスペルは「internationalization」なのですが、長すぎるのでi18nと表示しているようです。
これにより、アプリを多言語対応できます。
Railsのメッセージは英語なのですが、i18n用のgemをインストールし、翻訳用のja.ymlを定義した後、ビュー及びコントローラーをi18nを呼び出すように変更していくことで、日本語化することができます。
18nのインストール
Gemfileに追記しインストール
まずはGemfileにi18nを追加します。
# 日本語化 gem "rails-i18n", "~> 7.0.0"
さらに、
bundle install
でインストールします。
configに定義を追加
config/application.rbに、
module WagagunMy class Application < Rails::Application (中略) # 日本語化 config.i18n.available_locales = %i[ja en] config.i18n.default_locale = :ja # 複数のロケールファイルが読み込まれるようpathを通す config.i18n.load_path += Dir[Rails.root.join('config', 'locales', '**', '*.{rb,yml}').to_s] end end
を追記します。
localesディレクトリを作成し、テンプレート的なファイルを置く
localesディレクトリを作成し、以下のファイルを置いておきます。
(役に立つのかは不明ですが。)
https://raw.githubusercontent.com/svenfuchs/rails-i18n/master/rails/locale/en.yml
https://raw.githubusercontent.com/svenfuchs/rails-i18n/master/rails/locale/ja.yml
ja.ymlを記述
2つのディレクトリを作成し、ja.ymlを記述
あとは任意のディレクトリを作成し、そこにja.ymlを作成しますが、私はいくつかの参考サイトをもとにactiverecordとviewsの2つのディレクトリを作成し、それぞれにja.ymlを記述しました。
activerecordディレクトリのja.yml
config/locales/activerecord/ja.ymlは次の内容になっています。
ja: activerecord: models: project: 'プロジェクト' task: 'タスク' successful: messages: created: "%{model}に1件登録されました。" updated: "%{model}の情報が変更されました。" destroyed: "%{model}から1件削除されました。" attributes: task: description: '詳細' done: "完了" projet/tasks: description: "詳細" done: "完了" projet: tasks: 'タスク'
viewsディレクトリのja.yml
config/locales/views/ja.ymlは次の内容になっています。
zja: defaults: show: "詳細" back: "戻る" delete: "削除" edit: "変更" new: "新規作成" cancel: "キャンセル" save: "登録" views: pagination: first: '最初' last: '最後' previous: '前' next: '次' truncate: '...' projects: index: title: 'プロジェクト一覧' new: title: 'プロジェクト登録' edit: title: 'プロジェクト変更' show: title: 'プロジェクト詳細'
pagination:はkaminari(ページネーション用のgem)ですね。
ビューを記述
削除ガイダンスをヘルパーに記述
app/helpers/application_helper.rbにビューの削除ボタンのガイダンスに指定するconfirm_deleteを定義します。
module ApplicationHelper # 削除の確認メッセージ def confirm_delete return '本当に削除しますか?' end
index.html.haml
%h2= t ".title" %p#notice.text-success = notice (中略) = link_to (t "defaults.new"), new_project_path, class: 'btn btn-primary' (中略) %tbody - @projects.each do |project| (中略) = link_to (t "defaults.show"), project, class: 'btn btn-info' = link_to (t "defaults.edit"), edit_project_path(project), class: 'btn btn-primary' = button_to (t "defaults.delete"), project method: :delete, data: { turbo_confirm: confirm_delete }, class: 'btn btn-danger'
「t」で始まる箇所(タイトル、リンク、ボタン)が、日本語に置き換わります。
削除完了メッセージを表示するために、3〜4行目を追加します。
削除ボタンには、先程作成したconfirm_deleteを埋め込みます。
show.html.haml
%h2= t ".title" (中略) = link_to (t "defaults.edit"), edit_project_path(@project), class: 'btn btn-primary' \| = link_to (t "defaults.back"), projects_path, class: 'btn btn-secondary'
new.html.haml
%h2= t ".title" = render 'form' = link_to (t "defaults.back"), projects_path, class: 'btn btn-secondary'
「t」で始まる箇所(タイトル、リンク、ボタン)が、日本語に置き換わります。
edit.html.haml
%h2= t ".title" = render 'form' = link_to (t "defaults.show"), @project, class: 'btn btn-info' \| = link_to (t "defaults.back"), projects_path, class: 'btn btn-secondary'
「t」で始まる箇所(タイトル、リンク、ボタン)が、日本語に置き換わります。
.html.haml
= form_for @project do |f| - if @project.errors.any? #error_explanation %h4= t("errors.template.header", model: @project.model_name.human, count: @project.errors.count) %ul - @project.errors.full_messages.each do |message| %li= message
「t」で始まるバリデーションエラーメッセージが、日本語に置き換わります。
コントローラーを記述
app/controllers/projects_controller.rb
# POST /projects or /projects.json def create @project = Project.new(project_params) respond_to do |format| if @project.save #format.html { redirect_to project_url(@project), notice: "Project was successfully created." } format.html { redirect_to project_url(@project), :notice => "#{t('activerecord.successful.messages.created',:model => @project.model_name.human)}" } format.json { render :show, status: :created, location: @project } else format.html { render :new, status: :unprocessable_entity } format.json { render json: @project.errors, status: :unprocessable_entity } end end end # PATCH/PUT /projects/1 or /projects/1.json def update respond_to do |format| if @project.update(project_params) #format.html { redirect_to project_url(@project), notice: "Project was successfully updated." } format.html { redirect_to project_url(@project), :notice => "#{t('activerecord.successful.messages.updated',:model => @project.model_name.human)}" } format.json { render :show, status: :ok, location: @project } else format.html { render :edit, status: :unprocessable_entity } format.json { render json: @project.errors, status: :unprocessable_entity } end end end # DELETE /projects/1 or /projects/1.json def destroy @project.destroy respond_to do |format| #format.html { redirect_to projects_url, notice: "Project was successfully destroyed." } format.html { redirect_to projects_url, :notice => "#{t('activerecord.successful.messages.destroyed',:model => @project.model_name.human)}" } format.json { head :no_content } end end
「#{t(」で始まる各更新完了メッセージが、日本語に置き換わります。
(コメントになっている行は変更前の内容です。)<
最後に
とりあえず、これで、日本語表示ができるようになります。