Использование ApplicationMailer, получение ошибки неопределенного метода

#ruby-on-rails

#ruby-on-rails

Вопрос:

У меня это определено в моем application_mailer.rb

   def request_tutor(contact_name, contact_hp, contact_email, postal_code, contact_level, contact_subject, contact_lessons, contact_hours, contact_others)
    @contact_name = contact_name
    @contact_hp = contact_hp
    @contact_email = contact_email
    @contact_postal = postal_code
    @contact_level = contact_level
    @contact_subject = contact_subject
    @contact_lesson = contact_lessons
    @contact_hours = contact_hours
    @contact_others = contact_others
    mail(to:'example@example.com', subject: 'Tutor Request')
  end
  

и в соответствующем контроллере, где должно отображаться представление

   def request_tutor
      contact_name = params[:request_tutor][:contact_name]
      contact_email = params[:request_tutor][:contact_email]
      contact_hp = params[:request_tutor][:contact_hp]
      contact_postal = params[:request_tutor][:postal_code]
      contact_level = params[:request_tutor][:contact_level]
      contact_subject = params[:request_tutor][:contact_subject]
      contact_lesson = params[:request_tutor][:contact_lessons]
      contact_hours = params[:request_tutor][:contact_hours]
      contact_others = params[:request_tutor][:contact_others]
      ApplicationMailer.request_tutor(contact_name, contact_hp, contact_email, postal_code, contact_level, contact_subject, contact_lessons, contact_hours, contact_others).deliver
      flash[:success] = "We have received your request and will be in touch with you shortly!"
      redirect_to root_path
   end
  

У меня есть аналогичная настройка метода в action mailer и в соответствующем контроллере, который я делаю name = params[:checkout][:your_name] , и он не возвращает ошибку undefined method '[]' for nil:NilClass . Чего мне не хватает?

Ошибки из development.log

 Started GET "/" for 116.87.14.150 at 2016-10-10 23:02:37  0000
Cannot render console from 116.87.14.150! Allowed networks: 127.0.0.1, ::1, 127.0.0.0/127.255.255.255
  [1m[36mActiveRecord::SchemaMigration Load (0.5ms)[0m  [1mSELECT "schema_migrations".* FROM "schema_migrations"[0m
Processing by WelcomeController#index as HTML
  Rendered welcome/index.html.erb within layouts/application (390.7ms)
  Rendered layouts/_nav.html.erb (5.9ms)
  Rendered layouts/_messages.html.erb (0.6ms)
  Rendered layouts/_footer.html.erb (0.8ms)
Completed 200 OK in 641ms (Views: 608.3ms | ActiveRecord: 0.0ms)


Started GET "/welcome/request" for 116.87.14.150 at 2016-10-10 23:02:43  0000
Cannot render console from 116.87.14.150! Allowed networks: 127.0.0.1, ::1, 127.0.0.0/127.255.255.255
Processing by WelcomeController#request_tutor as HTML
Completed 500 Internal Server Error in 2ms (ActiveRecord: 0.0ms)

NoMethodError (undefined method `[]' for nil:NilClass):
  app/controllers/welcome_controller.rb:16:in `request_tutor'


  Rendered /usr/local/rvm/gems/ruby-2.3.0/gems/actionpack-4.2.5/lib/action_dispatch/middleware/templates/rescues/_source.erb (6.4ms)
  Rendered /usr/local/rvm/gems/ruby-2.3.0/gems/actionpack-4.2.5/lib/action_dispatch/middleware/templates/rescues/_trace.html.erb (3.8ms)
  Rendered /usr/local/rvm/gems/ruby-2.3.0/gems/actionpack-4.2.5/lib/action_dispatch/middleware/templates/rescues/_request_and_response.html.erb (1.5ms)
  Rendered /usr/local/rvm/gems/ruby-2.3.0/gems/actionpack-4.2.5/lib/action_dispatch/middleware/templates/rescues/diagnostics.html.erb within rescues/layout (110.0ms)
  

Комментарии:

1. Привет и добро пожаловать в Stack Overflow. Это произойдет, если params[:request_tutor] значение пусто (или params[:checkout] — вы используете оба в своем вопросе). Загляните в журналы вашего сервера (в log/development.log или в окне вашего терминала) и посмотрите, сможете ли вы найти там сообщение об ошибке … затем посмотрите на строки рядом с ним (обычно чуть выше) — которые должны показать вам params , что было отправлено на сервер при отправке запроса — возможно, чтоваши params сообщения отправляются не совсем так, как вы ожидаете.

2. Интересно то, что params[:checkout] это работает, поэтому я очень озадачен тем, почему это не работает сейчас. Он был настроен в соответствии с сегментом программы рассылки приложений из guides.rubyonrails.org . Я выполнил те же шаги для обоих, но один работает, а другой нет.

3. Круто … ооочень .. можете ли вы заглянуть в журналы вашего сервера, как я и просил 🙂 Это поможет нам точно определить проблему (которая может быть не в коде, который вы нам показали, а в коде, который настраивает параметры для ее отправки)

4. Я сделал, как вы сказали, скопировал и вставил его в свой первоначальный вопрос.

5. Хорошо, я очень сожалею об этом. В моем routes.rb, который я использую get 'welcome/request', to: 'welcome#request_tutor' , и в фактическом представлении я визуализирую <%= form_for :request_tutor, :url => welcome_request_tutor_path do |f| %>

Ответ №1:

итак, вы используете одно и то же действие как для настройки формы, так и для создания электронной почты. Вот где возникает проблема… потому что, когда вы впервые нажимаете на форму — она запускает request_tutor действие, но params[:request_tutor] его еще нет (потому что вы еще не отправили форму)… поэтому вам нужно проверить, существует ли это, прежде чем пытаться его создать.

например, это возможно:

 def request_tutor
  if params[:request_tutor].present?
    contact_name = params[:request_tutor][:contact_name]
    # ... lines skipped for brevity
    # you still need the ones in your original action
    ApplicationMailer.request_tutor(contact_name, contact_hp, contact_email, postal_code, contact_level, contact_subject, contact_lessons, contact_hours, contact_others).deliver
    flash[:success] = "We have received your request and will be in touch with you shortly!"
    redirect_to root_path
  end
  # If the code gets to here, there were no params, and the page
  # will just render the template named the same as the action
end
  

Комментарии:

1. Большое вам спасибо за помощь. Думаю, мне не пришло в голову проверить params.present .

2. Никаких проблем 🙂 мы все изучили этот материал в тот или иной момент 🙂