2017-12-13 5 views
0

私はまだ自分がRailsを初めて使うと考えています。 RailsアプリでSMS機能を実装しています。これは、今後の予定をクライアントに思い出させます。私の質問は、私は私の予定モデルではSMSメソッドを持っていますが、私のクライアントモデルは電話の属性が配置されている場所です。予定モデルから電話属性を呼び出すにはどうすればよいですか。ここでRailsの別のモデルの属性を読み取る方法

は私の約束モデルは、私の現在の団体のセットアップに基づいて

class Appointment < ApplicationRecord 
    enum status: { confirmed: 0, rescheduled: 1, cancelled: 2} 
    belongs_to :user 
    belongs_to :client 
    validates :start_time, presence: true 
    validates :end_time, presence: true 

    after_create :reminder 

    def reminder 
    @twilio_number = ENV['TWILIO_NUMBER'] 
    account_sid = ENV['TWILIO_ACCOUNT_SID'] 
    @client = Twilio::REST:Client.new account_sid, ENV['TWILIO_AUTH_TOKEN'] 
    time_str = ((self.start_time).localtime).strftime("%I:%M%p on %b. %d, %Y") 
    reminder = "Hi #{client.name}. Just a reminder that you have an appointment coming up at #{time_str}." 
    message = @client.api.account(account_sid).messages.create(
     :from => @twilio_number, 
     :to => client.phone_number, 
     :body => reminder, 
    ) 
    end 

私のクライアントモデル

class Client < ApplicationRecord 
    has_many :appointments 
    has_many :users, through: :appointments 

    scope :clients_by, ->(user) { where(user_id: user.id) } 
end 

です。リマインダーの変数では、私はちょうどPHONE_NUMBER属性にアクセスするために

reminder = "Hi #{client.name}.? 

そして

:to => client.phone_number 

のために呼び出すことができませんでしたか?

答えて

1

はい、正しいと仮定すると、client.<attribute>に電話することができます。

ただし、恐ろしいSELECT N + 1の問題に注意してください。あなたは50回の予定がある場合それでは、あなたが

Appointment.all.each do {|a| a.reminder } 

ような何かを言わせて、これはすべての予定、その後1により各クライアント1をロードするための呼び出しの束をロードするために、データベースへの51回の呼び出し、1回の呼び出しで結果。

この問題を回避するには、includes,eager_loads、またはpreloadを使用できます。これらのデータはすべて、個々のクエリより効率的に読み込まれます。

この3つの方法の違いについては、この記事のhttp://blog.scoutapp.com/articles/2017/01/24/activerecord-includes-vs-joins-vs-preload-vs-eager_load-when-and-whereで詳しく説明しています。私は以下のTL; DRの抜粋を引用しました。

私は大体このように、これらの方法に私のアプローチをまとめたい:私はちょうどフィルタリングてる 場合は、使用が参加します。 私が関係にアクセスしている場合は、インクルードから始めます。 includesが2つの別々のクエリを使って遅い場合、eager_loadを使用して1つのクエリを強制し、パフォーマンスを比較します。

ActiveRecord経由でリレーションシップにアクセスすると、多くのエッジケースが発生します。これにより、joins、includes、preload、およびeager_loadを使用する場合の基本的なパフォーマンスの低下を防ぐのに十分です。

Appointment.all.includes(:client).each do {|a| a.reminder } 
+0

は、私はちょうどこれを見たように、その記事のアドバイスの後、私たちは私の例を書き換えると思います。あなたの助けに感謝アンドリュー! – ryanb082

関連する問題