この頃、急に暑くなってきたせいか、蝉の鳴き声の幻聴が聞こえはじめた榊原です。
今回もVue.jsについて書こうかなと思いましたが、これは展開しておこうというものがあったので、Vue.jsのことではなく、Railsのことを書きます。
では、その内容はというと、タイトル通り「多対多モデルを利用しているビューのプレビューの実装」についてです。
早速本題となっていきますが、リレーションの記述については、他に色々な方たちがもっと詳しく説明してくれているので、今回は省略します。
今回説明用のモデルは以下の通りに設定されているものとします。
CompanyモデルがEventモデルと一対多の関係
CompanyモデルとCategoryモデルがCategoriesCompaniesモデルを中間モデルとして、多対多の関係となります
Companyモデル
- class Company < ApplicationRecord
- has_many: :events
- has_many: :categories, through: :categories_companies
- has_many: :categories_companies, dependent: :destroy, inverse_of: :company
- end
Eventモデル
- class Event < ApplicationRecord
- belongs_to: :company
- end
Categoryモデル
- class Category < ApplicationRecord
- has_many: :companies, through: :categories_companies
- has_many: :categories_companies, dependent: :destroy, inverse_of: :category
- end
CategoriesCompaniesモデル
- class CategoriesCompanies
- belongs_to :category
- belongs_to :company
- end
書き忘れてましたが前提として、ビューは通常とプレビューのものは同一のもので、かつ、保存しなくてもプレビューが見れる実装とします。
下記コントローラーの12〜14行目が今回の内容のキモで、疑似的に中間モデルにデータがあるときと同じ状態にします。
軽く説明すると、中間モデルにデータはないですが、Categoryモデルにはデータが存在しているので、直接Categoryモデルのデータを取得して、かつ、適した形にしてbuildメソッドを引き渡すことで、中間モデルにデータがある状態と同様の動作してくれるようになります。
ちなみに一体多や一体一の関係にあるモデルに関しては、モデルにしっかりリレーションが設定していなければ、保存をしていなくても、保存時と同じ参照の仕方で問題ありません。
- class ComapnyController < ActionController::Base
- # 通常
- def index
- @company = Company.includes(:event, :categories)
- end
- # プレビュー
- def preview
- @company = Company.new(params.require(:categories).permit(...))
- # 多対多のリレーションを疑似的に生成
- @company.categories.build(
- Category.where(id: attr[:category_ids]).map { |val| val.attributes }
- )
- render action: :index
- end
- end
ビューの内容に関しては特に説明する内容はないのですが、なぜ、通常とプレビューで同一のビューにするかというと、ビューを分けた方が実装的には簡単になりますが、その後の改修を行う際、ビューが2つになるので、改修コストがかかるのと、また、改修漏れが発生するリスクがあるためです。
- <ul>
- <%- @company.events do |event| %>
- <li><%- event.event_name %></li>
- <%- end %>
- </ul>
- <ul>
- <%- @company.categories. do |category| %>
- <li><%- category.category_name %></li>
- <%- end %>
- </ul>
railsを触り始めてから2年ぐらいになりますが、まだまだ日々書くコードが変わるほど奥が深いです。
また、リリースされた5.1で、webpack等も正式に対応されてフロント側との連携もしやすくなったので、そちらも触っていきたいと思います。
本当にrailsは痒いところに手が届くフレームワークだと思うので、すこしでも興味ある方は触ってみてください。
今回はサーバーサイドの内容だったので、次回はフロントサイドの内容でもと考えています。
しずおかオンライン中途採用社員も、積極募集中!
しずおかオンラインののスタッフとして、地域の魅力を伝える仕事です。
くわしくはこちら!