- Rails 5.0.0.1
- Ruby 2.3.1p112
- サイトA にアクセスしたときに 商品1 と 商品2 だけを表示
- サイトB にアクセスしたときに 商品3 だけを表示
したい
model で request 情報を取得できるようにする
application_controller.rb
class ApplicationController < ActionController::Base
protect_from_forgery with: :exception
before_filter :set_request_filter # 追記
# 追記
def set_request_filter
Thread.current[:request] = request
end
end
コントローラーで request オブジェクトを取得し、 Thread.current[:request] に入れておく
これでモデル内で Thread.current[:request] から request を参照できるようになります
scope の追加
site.rb
class Site < ApplicationRecord
has_many :items
# ドメイン名に domain カラムのキーワードが存在するデータを取得
scope :by_domain, lambda { |domain|
where("? LIKE CONCAT('%', domain, '%')", domain)
}
end
item.rb
class Item < ApplicationRecord
belongs_to :site
# request.host でドメイン名を取得し、Site.by_domain の引数に渡す
default_scope lambda {
request = Thread.current[:request]
return all unless request
joins(:site).merge(Site.by_domain(request.host))
}
end
Item インスタンス宣言時に、取得するデータを制限しておきたいので default_scope で実装
検証
適当にデータを作成します。
> site_a = Site.create(name: 'サイトA', domain: 'aaa') # domain はドメイン名に含まれる文字列を指定
> site_b = Site.create(name: 'サイトB', domain: 'bbb') # 上記と同様
> site_a.items.create(name: '商品1')
> site_a.items.create(name: '商品2')
> site_b.items.create(name: '商品3')
今回は pow を使って検証しました。
$ cd ~/.pow
$ ln -s ~/workspace/demo aaa
$ ln -s ~/workspace/demo bbb
ドメイン名は サイトA: aaa
、サイトB: bbb
にしておきます
また、Item モデルは事前に scaffold しています
アクセスしてみます
http://aaa.dev/items
- サイトA にアクセスしたときに 商品1 と 商品2 だけを表示
- サイトB にアクセスしたときに 商品3 だけを表示
できました
もっといいやり方があるよーな気がする。。
参考