22639


質問させていただきます。

RubyonRailsで、サイトを作成しております。  
モデルが更新された際に  
複数の宛先へのメールの送信を行おうと考えています。  
しかしMailerに送信したいユーザー一覧を渡すとエラーとなってしましました。

ユーザー一覧は、Applicantsという別のモデルのuser_idと  
一致するユーザーを抽出しております。

何か解決策があればご教授いただければと思います。

* * *

# エラーメッセージ

[code]

    ActiveJob::SerializationError in EventsController#update
    Unsupported argument type: ActiveRecord::Relation
    
[/code]

* * *

* * *

# events_controller.rb

[code]

    def update
      if  @event.update(event_params)
        applicants = @event.applicants
        @users = User.where(id: applicants.pluck(:user_id))
        EventMailer.update_to_applicants_email(@users,@event).deliver_later
      else
        render 'edit'
      end
    end
    
[/code]

* * *

* * *

# event_mailer.rb

[code]

    class EventMailer < ApplicationMailer
      default from: 'xxx@example.com'
    
      def update_to_applicants_email(users,event)
          @event = event
          mail to: users.pluck(:email)
          mail(subject: "#{@event.name}が更新されました")
      end
    end
    
[/code]

* * *

* * *

# pryで@usersを確認

[code]

    pry(#<EventsController>)> @users
    =>[#<User:0x007fef31ec4668
      id: 14,
      email: “111@example.com",
      中略
      >,
      #<User:0x007fef31ec4528
      id: 15,
      email: “222@example.com",
      中略
      >]
    
[/code]

* * *

なお、試しに@usersを@userにし、1人のuserを引き渡したところ、  
上記のエラーは発生しませんでした。

* * *

# pryで@userを確認

[code]

    pry(#<EventsController>)> @user
    =>#<User:0x007fef35520518
      id: 14,
      email: "111@example.com",
      中略
    >
    
[/code]

* * *

よろしくお願い致します。


CC BY-SA 3.0
2016-02-28T06:31:44.060
22621
2016-02-28T12:16:09.297
2020-06-17T08:14:45.997
-1
12734
question
ruby-on-rails ruby
ApplicationMailerのアクションに、配列を引数に渡すとSerializationErrorになる


エラーメッセージにもありますが、`Unsupported argument type: ActiveRecord::Relation` です。

ids の配列を渡しましょう。

[code]

    def update
      if  @event.update(event_params)
        applicants = @event.applicants       
        @users = User.where(id: applicants.pluck(:user_id))
    
        # 渡すのは、シリアライズできる要素で
        user_ids = @users.map(&:id)
        EventMailer.update_to_applicants_email(user_ids ,@event).deliver_later
    
    
      else
        render 'edit'
      end
    end
    
    class EventMailer < ApplicationMailer
      default from: 'xxx@example.com'
    
      def update_to_applicants_email(user_ids ,event)
    
          # 取り出すときに復旧する
          users = User.where(id: user_ids)
          @event = event
          mail to: users.pluck(:email)
          mail(subject: "#{@event.name}が更新されました")
      end
    end
    
[/code]

ApplicationMailer (というか内部で使っている Activejob)
は、キューに積むときに、文字列に変換します。変換できない形式だとエラーです。変換できるのは下記と、array, hash です。

[TYPE_WHITELIST = [ NilClass, Fixnum, Float, String, TrueClass, FalseClass,
Bignum, BigDecimal
]](https://github.com/rails/rails/blob/master/activejob/lib/active_job/arguments.rb#L37)

では、なぜ一つの時だけ成功するかというと、globalid というのが絡んできますが、長くなるので、知りたければ検索してみてください。


CC BY-SA 3.0
2016-02-28T12:10:23.533
22639
2016-02-28T12:16:09.297
2016-02-28T12:16:09.297
7471
7471
22621
answer