Rails отправляет электронную почту менеджеру на основе почтового индекса клиента, проходящего через три таблицы и связанную таблицу - PullRequest
0 голосов
/ 18 января 2019

Поэтому я пытаюсь установить, где клиент вводит свою контактную информацию (таблица клиентов), которая затем проверяет базу данных (почтовый индекс) и отправляет электронное письмо менеджеру (регион). Однако данные клиента разделены. Во-первых, фамилия, телефон, электронная почта и имя организации хранятся в клиенте. Адреса доставки и выставления счетов хранятся в CustomerAddress вместе с идентификатором для Клиента Shipping_Address_ID.

Модель

Customer
  [:billing_address, :shipping_address].each do |assocation|
    belongs_to assocation,
      class_name: CustomerAddress.to_s,
      required: false,
      dependent: :destroy
  end

Zipcode
belongs_to :region
validates :zipcode, presence: true

Region
has_many :zipcodes, dependent: :destroy
validates :name, presence: true
validates :email, presence: true

class CustomerForm
  include ActiveModel::Model

  CUSTOMER_ATTRS = %w[
    first_name last_name phone email title
    business_name trade_name business_phone business_fax
    business_email business_segments
  ].freeze

  ADDRESS_ATTRS = %w[
    address1 address2 city state zip
  ].freeze

  attr_accessor(*CUSTOMER_ATTRS)
  attr_accessor(*ADDRESS_ATTRS.map { |attr| 'billing_' + attr })
  attr_accessor(*ADDRESS_ATTRS.map { |attr| 'shipping_' + attr })
  attr_accessor :confirm_email, :captcha_response, :shipping_is_billing

  validates :first_name, :last_name, :phone, :email, :title,
:business_name, :trade_name, :business_phone, :business_fax,
:business_email, :business_segments,
presence: true

  validate :email_is_confirmed, :captcha_passes

  validates :billing_address1, :billing_city, :billing_state, :billing_zip,
presence: true

  validates :shipping_address1, :shipping_city, :shipping_state, :shipping_zip,
presence: true, unless: :shipping_is_billing

  def save
    return false unless valid?

    persist!
  end

  private

  def email_is_confirmed
    return if confirm_email.present? && email == confirm_email

    errors.add(:confirm_email, 'must equal email')
  end

  def captcha_passes
    captcha = Captcha.new
    return if captcha.valid?(captcha_response)

    errors.add(:captcha_response, 'is invalid')
  end

  def persist!
    customer = Customer.new(attrs_for_customer)
    customer.billing_address = CustomerAddress.new(attrs_for_address('billing_'))
    customer.shipping_address = CustomerAddress.new(
      attrs_for_address(shipping_is_billing ? 'billing_' : 'shipping_')
    )
    customer.save!
    CustomerMailer.registration(customer).deliver_later
    customer
  end

  def attrs_for_customer
    Hash[
      CUSTOMER_ATTRS.map { |attr| [attr, send(attr)] }
    ]
  end

  def attrs_for_address(prefix)
    Hash[
      ADDRESS_ATTRS.map { |attr| [attr, send(prefix + attr.to_s)] }
    ]
  end
end

Очевидно, что CustomerAddress использует модель / приложение вместо модели, но действует как модель.

Я не могу понять запрос / метод для этого. Я понимаю, что соединения что-то вроде:

Customer.shipping_address_id = CustomerAddress.id
CustomerAddress.zip = Zipcode.zipcode
Zipcode.region_id = Region.id output Region.email

Как мне взять CustomerAddress.zip и выполнить итерацию / сравнение по модели Zipcode, а затем связать данные клиента с регионом?

Я пробовал следующее:

def something(customer)
 @zipcode = Zipcode.find_by(zipcode: customer.zip)
 @manager = @zipcode.try(:region)
 if @manager
   CustomerMailer.notify_manager(customer, @manager).deliver_later
 else
   CustomerMailer.notify_hq(customer).deliver_later
 end
end

Это не ошибка, однако это не генерирует электронную почту.

Так что я обновил его дальше и удалил почтовик под постоянным! метод с email_notification (клиент)

Затем создано:

def email_notification(customer)
 @region = Region.all
 @zipcode = Zipcode.find_by(zipcode: customer.shipping_address.zip)
 @manager = @zipcode.find_by(region_id: @region.ids)
 if @manager
   CustomerMailer.notify_manager(customer, @manager).deliver_later
 else
   CustomerMailer.registration(customer).deliver_later
 end
end

Тем не менее, я получаю неопределенный метод find_by для # в @manager.

Я заметил, что существует проблема с хранением данных, когда я получаю фактический shipping_address_id, поэтому я обновил метод до:

def email_notification(customer)
 @region = Region.all
 @customer_address = customer.where.not(shipping_address_id: '')
 @zipcode = Zipcode.find_by(zipcode: @customer_address.zip)
 @manager = @zipcode.find_by(region_id: @region.ids)
 if @manager
  CustomerMailer.notify_manager(customer, @manager).deliver_later
 else
  CustomerMailer.registration(customer).deliver_later
 end
end

В результате

неопределенный метод `где ' В частности, на @customer_address.

Ответы [ 2 ]

0 голосов
/ 24 января 2019

Вы вызываете метод 'where' для экземпляра класса.И вам нужно сделать это против коллекции, и для этого вы должны сначала получить все адреса клиентов.Кстати, вы не предоставили никакой информации о классе CustomerAddress.

Я могу предложить, что это должно быть примерно так:

@customer = Customer.find(name: 'Bob')  # you found customer
@customer_addresses = @customer.shipping_address # you got customer addresses

Теперь вы можете сделать это @scoped_addresses = @customer_addresses.where('your query'), ночтобы сделать это, вы должны изменить направление ассоциации на наоборот.Клиент has_many :shipping_adresses, class_name: CustomerAddresses И получите

@zip = @scoped_addresses.find('some criteria').shipping_zip

и дальше вы можете перейти

@manager = Region.joins(:zipcodes).where(zipcodes: {zipcode: @zip}).manager

PS Было бы здорово, если вы ознакомитесь с Учение

0 голосов
/ 23 января 2019

Так что я бросил на binding.pry под каждую строку, и он, наконец, щелкнул.

def email_notification(customer)
 if customer.shipping_address_id.presence
   @zipcode = Zipcode.find_by(zipcode: customer.shipping_address.zip)
   @manager = @zipcode.region.region_email
   if @manager.presence
     CustomerMailer.notify_manager(customer, @manager).deliver_later
   else
     CustomerMailer.registration(customer).deliver_later
   end
 end
end

На самом деле это не электронная почта notify_manager, но это другая проблема.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...