8
13

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Ruby on Rails 遷移元によって条件を変更させる2パターン

Posted at

プログラミングスクールのチーム開発でECサイトを作成している際、
どこのリンク先から遷移したかでインスタンス変数を変えたい・・・
というような場面がありました。
その時に2パターンの方法があったので、備忘録として残します。

【環境】
Ruby: 2.5.7
Rails: 5.2.4
使用した中で関係するgem:devise(顧客、管理者を作成)

前提条件

  • 管理者側のページで注文一覧を表示する際、下記のように設定したい。
  • トップページから遷移 => 本日作成された注文一覧
  • 顧客の詳細ページから遷移 => その顧客の注文一覧
  • ヘッダーの注文一覧ボタンから遷移 => 全ての注文一覧

テーブル

schema.rb
create_table "orders", force: :cascade do |t|
   t.integer "user_id", null: false
   (略)
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
  end

create_table "users", force: :cascade do |t|
   (略)
  end

モデル(アソシエーション)

user.rb
has_many :orders, dependent: :destroy
order.rb
belongs_to :user

ルート

namespace :admins do
    get '', to: 'products#top'
    resources :users, only: [:index, :show, :edit , :update]
    resources :orders, only: [:index, :show, :update]
end

実装パターン①:遷移元をコントローラで取得する

参考にした記事:Railsで遷移元のコントローラーとアクションを取得する

admins/orders_controller.rb
def index
 path = Rails.application.routes.recognize_path(request.referer)

 # path[:controller]で遷移元コントローラーを、path[:action]でアクションを取得
 if path[:controller] == "admins/products" && path[:action] == "top"
   @orders = Order.where(created_at: Date.today)
  elsif  path[:controller] == "admins/users" && path[:action] == "show"
    @orders = Order.where(user_id: path[:id])
  else 
   @orders = Order.all
  end
end

これで、3パターンの変数を持たせることができました。
ただ、この内容だと【トップ画面からヘッダーの注文履歴ボタンを押した】際、
トップ画面から遷移したと判断されてしまいます。
そのため、最終的には下記の方法で実装を行いました。

実装パターン②:リンク元にパラメーターを付ける

遷移元のリンクページには下記の通りパラメータを持たせました。

admins/products/top.html.erb
 <%= link_to "本日の注文件数", admins_orders_path(order_sort: 0) %>
admins/users/show.html.erb
 <%= link_to "注文一覧", admins_orders_path(order_sort: 1) %>

そしてコントローラ側では、持ってきたパラメーターで変数を振り分け

admins/orders_controller.rb
def index
 case params[:order_sort]
 when "0"
   @orders = Order.where(created_at: Date.today)
 when "1"
   @user = User.find(params[:user_id])
   @orders = @user.orders
 else
   @orders = Order.all
 end
end

これによって①の問題は解消されました。

まとめ

  • ①の方法であればコントローラ側で一目見れば分岐条件がわかりやすいと思うが、状況に応じた実装が求められる。
  • ①の方法を応用すれば、updateやdestroyアクションのリダイレクト先などを分岐させることも可能。
8
13
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
13

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?