1

私は通知モデルを持っています:

Notification(id: integer, notifiable_id: integer, notifiable_type: string, user_id: integer, created_at: datetime, updated_at: datetime)

通知コントローラー:

def index
  @notifications = current_user.notifications.page(params[:page]).per(10)
end

ビューでは、レコードが次のように表示されます。

user1 が post1 にコメントしました
user2 が post1 にコメントしました
user3 が blog1 を購読しました user4 が
blog1 を購読しました

notifiable代わりにグループ化して表示するにはどうすればよいですか:

user1、user2 が post1 にコメントしました
user3、user4 が blog1 を購読しました

4

1 に答える 1

3

応答は、使用するデータベースによって異なります。

Postgresql

postgres の場合、次のようなことができます。

@notifications = current_user.notifications.
                 select( "string_agg( users.user_name, ', ' ) as user_names, notifiables.name as notifiable_name" ).
                 group( 'notifiables.name, notifications.notifiable_type' ).
                 joins( :notifiable ).joins( :user ).
                 page(params[:page]).per(10)

次に、集約されたオブジェクトを次のように使用します。

@notifications.map { |n| "#{n.user_names} #{n.notifiable_type} #{n.notifable_name}" }

他のテーブルのフィールド名を推測したので、それに応じて調整してください。

基本的な考え方は、結果をグループ化し、データベース連結機能を使用することです。Kaminari と will_paginate は結果をうまく処理します。

注意: を使用するときはいつものように#select、オブジェクトをデータベースに書き戻さないでください。オブジェクトが破損します。

MySql

mysql の場合、これは基本的に同じはずですがstring_agg( users.user_name, ', ' )group_concat( users.user_name )

于 2013-09-21T11:51:21.153 に答える