Rails: отправка электронных писем, получение неопределенного метода `model_name 'для Mail :: Message: Class - PullRequest
1 голос
/ 12 февраля 2012

Мои навыки в Rails (если быть добрыми) ржавые, так что это, вероятно, вопрос новичка. Я пытаюсь создать простую форму для отправки электронной почты, но получаю:

NoMethodError in Mail#create
undefined method `model_name' for Mail::Message:Class

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

def create
  @mail = Mail.new(params[:mail])
  MailMailer.send_mail(@mail).deliver
end

Думает, что эта строка вызывает ошибку @mail = Mail.new(params[:mail]). Моя модель класса Mail выглядит так:

class Mail < ActiveRecord::Base
  include ActiveModel::Validations
  validates :password, :presence => true
  attr_accessor :password, :to, :cc, :bcc, :from, :subject, :message
end

А мой почтовик выглядит так:

class MailMailer < ActionMailer::Base
  def send_mail(mail)
    mail(:to => mail.to, :subject => mail.subject)
  end
end

Кто-нибудь может заметить, что я делаю неправильно?

1 Ответ

2 голосов
/ 12 февраля 2012

Ваша проблема, вероятно, именно здесь:

class Mail < ActiveRecord::Base
  # ---------^^^^^^^^^^^^^^^^^^
  include ActiveModel::Validations
  validates :password, :presence => true
  attr_accessor :password, :to, :cc, :bcc, :from, :subject, :message
end

Подклассы ActiveRecord::Base и включение ActiveModel::Validations немного странно, так как AR уже включает все элементы проверки.Смешивание AR и attr_accessor является еще одним признаком того, что происходит что-то странное.

В ваших комментариях вы отмечаете, что создали эту модель с:

$ rails g model mail

И она пытается создать базу данныхподдерживаемая модель ActiveRecord, поскольку это почти всегда то, что люди хотят.Вы также можете столкнуться с проблемами из-за того, что Mail уже используется, поэтому, возможно, вы захотите использовать другое имя.

Если вам нужна модель, представляющая собой временный пакет данных, вы можете сделать это:

class SomeEmail
  attr_accessor :password, :to, :cc, :bcc, :from, :subject, :message
end

Возможно, вам здесь не нужны проверки, но вы можете добавить их:

class SomeEmail
  include ActiveModel::Validations
  validates :password, :presence => true
  attr_accessor :password, :to, :cc, :bcc, :from, :subject, :message
end

, но проверки не будут запущены, если вы не вызовете valid? вручную, поэтомунет особого смысла.

Наконец, простое добавление attr_accessor не даст вам полезного конструктора, поэтому со всеми вышеперечисленными изменениями это:

@mail = SomeMail.new(params[:mail])

все равно не будет делать то, чтоВы хотите, чтобы ничего в params[:mail] нигде не сохранялось.Поэтому добавьте реализацию initialize в свой класс электронной почты и вызов valid? на свой контроллер.

...