2015-01-12 15 views
14

ile deliver_later kullanarak. Ancak, delivery_later nesneyi serileştirmeye çalıştığı ve her seferinde başarısız olduğu için yalnızca delivery_now'un çalışmasını sağlayabiliyorum. İşte Raylar 4.2: Ben kurulum için Raylar 4.2 en deliver_later yöntemini kullanarak bir iletişim formu çalışıyorum bir tablosuz modeli

benim Kurulum:

messages_controller.rb

class MessagesController < ApplicationController 
    def new 
    @message = Message.new 
    end 

    def create 
    @message = Message.new(params[:message]) 
    if @message.valid? 
     ContactMailer.contact_form(@message).deliver_later 
     redirect_to root_path, notice: "Message sent! Thank you for contacting us." 
    else 
     render :new 
    end 
    end 
end 

contact_mailer.rb

class ContactMailer < ApplicationMailer 
    default :to => Rails.application.secrets['email'] 

    def contact_form(msg) 
    @message = msg 
    mail(:subject => msg.subject, from: msg.email) 
    end 
end 

message.rb

class Message 
    include ActiveModel::Model 
    include ActiveModel::Conversion 

    ## Not sure if this is needed ## 
    include ActiveModel::Serialization 

    extend ActiveModel::Naming 

    attr_accessor :name, :subject, :email, :body 

    validates_presence_of :email, :body 
    validates_format_of :email, with: /\A([^\s]+)((?:[-a-z0-9]\.)[a-z]{2,})\z/i 
    validates_length_of :body, :maximum => 1000 

    def initialize(attributes = {}) 
     attributes.each { |name, value| send("#{name}=", value) } 
    end 

    ## Not sure if this is needed ## 
    def attribtues 
     {'name' => nil, 'subject' => nil, 'email' => nil, 'body' => nil} 
    end 
end 

ContactMailer.contact_form(@message).deliver_later çağrılırken alıyorum hatadır:

ActiveJob::SerializationError in MessagesController#create 

Unsupported argument type: Message 
Extracted source (around line #10): 
if @message.valid? 
    ContactMailer.contact_form(@message).deliver_later 
    redirect_to root_path, notice: "Message sent! Thank you for contacting us." 
else 
    render :new 

İdeal Bunun bir arka plan işlemi olmak istiyorum. Yakında Sidekiq gibi bir şey ekleyeceğim ama sanırım en iyisi bu serileştirme problemini önceden düzeltmek.

Herhangi bir yardım için teşekkür ederiz! Thanks :) AJ geçmeden önce nesne seri ve mailler serisini gerekir

cevap

10

Sınıfınızı ActiveJob (deliver_later delegesinin yaptığı) ile kullanmak için, nesnenin kimliğini benzersiz olarak tanımlayabilmesi gerekir. Ayrıca, daha sonra seri hale getirme işleminde kimliğin kimliğini bulması gerekir (mailer/işlerde manuel seriye dönüş yapılması gerekmez).

class Message 
    ... 
    include GlobalID::Identification 
    ... 

    def id 
    ... 
    end 

    def self.find(id) 
    ... 
    end 
end 

ActiveRecord bu yöntemlerle size sağlayacaktır ancak kullanmaya değiliz çünkü, bunu kendiniz uygulamak gerekir. Eğer kayıt saklamak istiyor ama dürüstçe sana altına ActiveRecord ve tabloyu kullanarak daha iyi olurdu düşünmek nerede karar vermek size kalmış.

+0

Sadece ActiveRecord ve onun temelini kullanarak bitti. – DaniG2k

+1

@ DaniG2k ActiveRecord'u tableless modelle nasıl kullandınız? – Marklar

+1

@Marklar Sanırım altta yatan bir tablo kullandığını söylüyor. – Nick

8

gereksiz bir tablo ActiveRecord nesneyi geri ya da oluşturmak zorunda kalınmaz basit bir çözüm: CONTACT_FORM yöntemine mesaj nesnesi geçme yerine

, ayrıca CONTACT_FORM yöntemine ve daha sonra parametreler mesaj geçebilir Message nesnesini bu yöntemin içinde başlatır.

Bu

Eğer gecikmeli iş işçinin bellek uzayda nesne başlatılırken, çünkü bir tablo oluşturmak zorunda kalmadan sorunu çözecektir. Örneğin

:

messages_controller.rb

MessagesController < ApplicationController 
    def new 
     @message = Message.new 
    end 

    def create 
     @message = Message.new(params[:message]) 

     if @message.valid? 
      ContactMailer.contact_form(params[:message]).deliver_later 
      redirect_to root_path, notice: "Message sent! Thank you for contacting us." 
     else 
      render :new 
     end 
    end 
end 

contact_mailer.rb

class ContactMailer < ApplicationMailer 
    default :to => Rails.application.secrets['email'] 

    def contact_form(msg_params) 
     @message = Message.new(msg_params) 
     mail(:subject => msg.subject, from: msg.email) 
    end 
end 
+0

Bu harika bir çözümdür. Teşekkür ederim! –

+0

Bu, Rails 5'te çalışmaz: 'Desteklenmeyen argüman türü: ActionController :: Parameters' – Vadim

2

Bugün benzer bir sorun vardı ve şöyle çözdü.

    • Rayları

Çevre karma dönüştür bir postasının

  • için bir JSON sokması halinde json dize
  • Geçiş bir tablosuz nesne dönüştürme 5.0.2
  • messages_controller.rb

    class MessagesController < ApplicationController 
    
        # ... 
    
        def create 
        @message = Message.new(message_params) 
        if @message.valid? 
         ContactMailer.contact_form(@message.serialize).deliver_later 
         redirect_to root_path, notice: "Message sent! Thank you for contacting us." 
        else 
         render :new 
        end 
        end 
    
        # ... 
    end 
    

    contact_mailer.rb

    class ContactMailer < ApplicationMailer 
        default :to => Rails.application.secrets['email'] 
    
        def contact_form(message_json) 
        @message = JSON.parse(message_json).with_indifferent_access 
    
        mail(subject: @message[:subject], from: @message[:email]) 
        end 
    end 
    

    message.rb bu kimseye yardımcı olacaktır

    class Message 
        include ActiveModel::Model 
    
        attr_accessor :name, :subject, :email, :body 
    
        validates_presence_of :email, :body 
        validates_format_of :email, with: /\A([^\s]+)((?:[-a-z0-9]\.)[a-z]{2,})\z/i 
        validates_length_of :body, :maximum => 1000 
    
        # Convert an object to a JSON string 
        def serialize 
        ActiveSupport::JSON.encode(self.as_json) 
        end 
    end 
    

    Umut.

    İlgili konular