ページのイメージ
WEB開発 2017/07/05

[Rails]多対多モデルを利用しているビューのプレビュー実装について

榊原継太
榊原継太
  •  
  • このエントリーをはてなブックマークに追加

rails

この頃、急に暑くなってきたせいか、蝉の鳴き声の幻聴が聞こえはじめた榊原です。

今回も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は痒いところに手が届くフレームワークだと思うので、すこしでも興味ある方は触ってみてください。

今回はサーバーサイドの内容だったので、次回はフロントサイドの内容でもと考えています。

Category

Ranking