Вопрос или проблема
Я добавляю систему уведомлений на свой блог с помощью гема noticed (v2) от Криса Оливера. Я настроил уведомитель для отправки электронных уведомлений, но сталкиваюсь с ошибкой: ArgumentError (неверное количество аргументов (дано 0, ожидается 1))
. Похоже, что ожидается параметр, который не был предоставлен. Как я могу решить эту ошибку и убедиться, что уведомление получает правильный аргумент?
usermailer.rb
class UserMailer < ApplicationMailer
# Тема может быть установлена в вашем файле I18n в config/locales/en.yml
# с помощью следующего поиска:
#
# en.user_mailer.new_comment.subject
#
def new_comment
@greeting = "Привет"
mail to: params[:user].email
end
end
comment_notifier.rb
# Чтобы отправить это уведомление:
#
# CommentNotifier.with(record: @post, message: "Новый пост").deliver(User.all)
class CommentNotifier < ApplicationNotifier
# Добавьте ваши методы доставки
#
deliver_by :email do |config|
config.mailer = "UserMailer"
config.method = "new_comment"
# почему эта строка ожидает аргумент
config.params = ->(recipient) { { user: recipient } }
end
#
# bulk_deliver_by :slack do |config|
# config.url = -> { Rails.application.credentials.slack_webhook_url }
# end
#
# deliver_by :custom do |config|
# config.class = "MyDeliveryMethod"
# end
# Добавьте необходимые параметры
#
# required_param :message
end
Я вызываю уведомитель из консоли rails как
CommentNotifier.with(record: Comment.last, message: "Новый пост").deliver(User.last)
ниже приведен трейс стека
Загрузка среды разработки (Rails 7.0.7.2)
irb(main):001:0> CommentNotifier.with(record: Comment.last, message: "Новый пост").deliver(User.last)
Comment Load (0.4ms) SELECT "comments".* FROM "comments" ORDER BY "comments"."id" DESC LIMIT $1 [["LIMIT", 1]]
User Load (0.5ms) SELECT "users".* FROM "users" ORDER BY "users"."id" DESC LIMIT $1 [["LIMIT", 1]]
ТРАНЗАКЦИЯ (0.2ms) BEGIN
CommentNotifier Create (0.5ms) INSERT INTO "noticed_events" ("type", "record_type", "record_id", "params", "created_at", "updated_at", "notifications_count") VALUES ($1, $2, $3, $4, $5, $6, $7) RETURNING "id" [["type", "CommentNotifier"], ["record_type", "Comment"], ["record_id", 35], ["params", "{\"message\":\"Новый пост\",\"_aj_symbol_keys\":[\"message\"]}"], ["created_at", "2024-11-08 18:45:25.508349"], ["updated_at", "2024-11-08 18:45:25.508349"], ["notifications_count", 1]]
Noticed::Notification Insert (0.4ms) INSERT INTO "noticed_notifications" ("type","recipient_type","recipient_id","event_id","created_at","updated_at") VALUES ('CommentNotifier::Notification', 'User', 5, 38, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP) RETURNING "id"
ТРАНЗАКЦИЯ (44.3ms) COMMIT
Добавлено в очередь Noticed::EventJob (ID задачи: 4e4dd3f7-1629-4119-acd8-f346a488861c) для Async(default) с аргументами: #<GlobalID:0x000077596c7dd240 @uri=#<URI::GID gid://student-connect-hub/CommentNotifier/38>>
=>
#<CommentNotifier:0x000077596ce5e178
id: 38,
type: "CommentNotifier",
record_type: "Comment",
record_id: 35,
params: {:message=>"Новый пост"},
created_at: Пт, 08 Ноя 2024 18:45:25.508349000 UTC +00:00,
updated_at: Пт, 08 Ноя 2024 18:45:25.508349000 UTC +00:00,
notifications_count: 1>
irb(main):002:0> CommentNotifier Load (0.4ms) SELECT "noticed_events".* FROM "noticed_events" WHERE "noticed_events"."type" = $1 AND "noticed_events"."id" = $2 LIMIT $3 [["type", "CommentNotifier"], ["id", 38], ["LIMIT", 1]]
Выполнение Noticed::EventJob (ID задачи: 4e4dd3f7-1629-4119-acd8-f346a488861c) из Async(default) в 2024-11-08T18:45:25Z с аргументами: #<GlobalID:0x000077596cea0fa0 @uri=#<URI::GID gid://student-connect-hub/CommentNotifier/38>>
Noticed::Notification Load (0.4ms) SELECT "noticed_notifications".* FROM "noticed_notifications" WHERE "noticed_notifications"."event_id" = $1 [["event_id", 38]]
Добавлено в очередь Noticed::DeliveryMethods::Email (ID задачи: 6ef6cdfa-7c81-474f-8d4d-08449c6dfd5b) для Async(default) с аргументами: :email, #<GlobalID:0x000077596cb8fe38 @uri=#<URI::GID gid://student-connect-hub/CommentNotifier::Notification/59>>
Выполнено Noticed::EventJob (ID задачи: 4e4dd3f7-1629-4119-acd8-f346a488861c) из Async(default) за 162.98ms
CommentNotifier::Notification Load (0.4ms) SELECT "noticed_notifications".* FROM "noticed_notifications" WHERE "noticed_notifications"."type" = $1 AND "noticed_notifications"."id" = $2 LIMIT $3 [["type", "CommentNotifier::Notification"], ["id", 59], ["LIMIT", 1]]
Выполнение Noticed::DeliveryMethods::Email (ID задачи: 6ef6cdfa-7c81-474f-8d4d-08449c6dfd5b) из Async(default) добавлено в очередь на 2024-11-08T18:45:25Z с аргументами: :email, #<GlobalID:0x000077596cba7b78 @uri=#<URI::GID gid://student-connect-hub/CommentNotifier::Notification/59>>
Noticed::Event Load (0.4ms) SELECT "noticed_events".* FROM "noticed_events" WHERE "noticed_events"."id" = $1 LIMIT $2 [["id", 38], ["LIMIT", 1]]
Ошибка при выполнении Noticed::DeliveryMethods::Email (ID задачи: 6ef6cdfa-7c81-474f-8d4d-08449c6dfd5b) из Async(default) за 108.72ms: ArgumentError (неверное количество аргументов (дано 0, ожидается 1)):
/home/code-machine/Desktop/work/StudentConnectHub/app/notifiers/comment_notifier.rb:13:in `block (2 levels) in <class:CommentNotifier>'
/home/code-machine/.rbenv/versions/3.2.2/lib/ruby/gems/3.2.0/gems/noticed-2.4.3/lib/noticed/delivery_method.rb:50:in `instance_exec'
/home/code-machine/.rbenv/versions/3.2.2/lib/ruby/gems/3.2.0/gems/noticed-2.4.3/lib/noticed/delivery_method.rb:50:in `evaluate_option'
/home/code-machine/.rbenv/versions/3.2.2/lib/ruby/gems/3.2.0/gems/noticed-2.4.3/lib/noticed/delivery_methods/email.rb:15:in `params'
/home/code-machine/.rbenv/versions/3.2.2/lib/ruby/gems/3.2.0/gems/noticed-2.4.3/lib/noticed/delivery_methods/email.rb:10:in `deliver'
/home/code-machine/.rbenv/versions/3.2.2/lib/ruby/gems/3.2.0/gems/noticed-2.4.3/lib/noticed/delivery_method.rb:32:in `block in perform'
/home/code-machine/.rbenv/versions/3.2.2/lib/ruby/gems/3.2.0/gems/activesupport-7.0.7.2/lib/active_support/callbacks.rb:99:in `run_callbacks'
/home/code-machine/.rbenv/versions/3.2.2/lib/ruby/gems/3.2.0/gems/noticed-2.4.3/lib/noticed/delivery_method.rb:31:in `perform'
/home/code-machine/.rbenv/versions/3.2.2/lib/ruby/gems/3.2.0/gems/activesupport-7.0.7.2/lib/active_job/execution.rb:65:in `block in _perform_job'
/home/code-machine/.rbenv/versions/3.2.2/lib/ruby/gems/3.2.0/gems/activesupport-7.0.7.2/lib/active_support/callbacks.rb:118:in `block in run_callbacks'
/home/code-machine/.rbenv/versions/3.2.2/lib/ruby/gems/3.2.0/gems/i18n-1.14.1/lib/i18n.rb:322:in `with_locale'
/home/code-machine/.rbenv/versions/3.2.2/lib/ruby/gems/3.2.0/gems/activesupport-7.0.7.2/lib/active_job/translation.rb:9:in `block (2 levels) in <module:Translation>'
/home/code-machine/.rbenv/versions/3.2.2/lib/ruby/gems/3.2.0/gems/activesupport-7.0.7.2/lib/active_support/callbacks.rb:127:in `instance_exec'
/home/code-machine/.rbenv/versions/3.2.2/lib/ruby/gems/3.2.0/gems/activesupport-7.0.7.2/lib/active_support/callbacks.rb:127:in `block in run_callbacks'
/home/code-machine/.rbenv/versions/3.2.2/lib/ruby/gems/activesupport-7.0.7.2/lib/active_support/core_ext/time/zones.rb:65:in `use_zone'
/home/code-machine/.rbenv/versions/3.2.2/lib/ruby/gems/activesupport-7.0.7.2/lib/active_job/timezones.rb:9:in `block (2 levels) in <module:Timezones>'
/home/code-machine/.rbenv/versions/3.2.2/lib/ruby/gems/activesupport-7.0.7.2/lib/active_support/callbacks.rb:127:in `instance_exec'
/home/code-machine/.rbenv/versions/3.2.2/lib/ruby/gems/activesupport-7.0.7.2/lib/active_support/callbacks.rb:127:in `block in run_callbacks'
/home/code-machine/.rbenv/versions/3.2.2/lib/ruby/gems/activesupport-7.0.7.2/lib/active_support/callbacks.rb:138:in `run_callbacks'
/home/code-machine/.rbenv/versions/3.2.2/lib/ruby/gems/activesupport-7.0.7.2/lib/active_job/execution.rb:28:in `execute'
/home/code-machine/.rbenv/versions/3.2.2/lib/ruby/gems/3.2.0/gems/activejob-7.0.7.2/lib/active_job/queue_adapters/async_adapter.rb:70:in `perform'
/home/code-machine/.rbenv/versions/3.2.2/lib/ruby/gems/3.2.0/gems/concurrent-ruby-1.2.2/lib/concurrent-ruby/concurrent/executor/ruby_thread_pool_executor.rb:352:in `run_task'
/home/code-machine/.rbenv/versions/3.2.2/lib/ruby/gems/3.2.0/gems/concurrent-ruby-1.2.2/lib/concurrent-ruby/concurrent/executor/ruby_thread_pool_executor.rb:343:in `block (3 уровня) в create_worker'
/home/code-machine/.rbenv/versions/3.2.2/lib/ruby/gems/concurrent-ruby-1.2.2/lib/concurrent-ruby/concurrent/executor/ruby_thread_pool_executor.rb:334:in `loop'
/home/code-machine/.rbenv/versions/3.2.2/lib/ruby/gems/concurrent-ruby-1.2.2/lib/concurrent-ruby/concurrent/executor/ruby_thread_pool_executor.rb:334:in `block (2 уровня) в create_worker'
/home/code-machine/.rbenv/versions/3.2.2/lib/ruby/gems/concurrent-ruby-1.2.2/lib/concurrent-ruby/concurrent/executor/ruby_thread_pool_executor.rb:333:in `catch'
/home/code-machine/.rbenv/versions/3.2.2/lib/ruby/gems/concurrent-ruby-1.2.2/lib/concurrent-ruby/concurrent/executor/ruby_thread_pool_executor.rb:333:in `block in create_worker'
.
Ответ или решение
Ошибка ArgumentError (wrong number of arguments (given 0, expected 1))
, с которой вы столкнулись, связана с тем, что метод, вызываемый вашим UserMailer
, ожидает аргумент, но он не был ему передан. Рассмотрим подробнее, какие шаги необходимо предпринять для устранения этой ошибки и корректной передачи необходимых параметров вашему почтовому уведомлению.
1. Анализ проблемы
В вашем коде класс UserMailer
содержит метод new_comment
, который определен без параметров. Однако, при использовании данного метода через CommentNotifier
, в блоке конфигурации deliver_by :email
ожидается, что метод примет один параметр — получателя уведомления, который будет передан при его вызове. В данном случае, код:
config.params = ->(recipient) { { user: recipient } }
передает recipient
в хэш параметров, который потом должен использоваться в методе new_comment
. Поскольку метод new_comment
не имеет параметров, это и вызывает ошибку.
2. Решение проблемы
Чтобы исправить исходную ошибку, вам необходимо обновить метод new_comment
с учетом принятия параметров. Он должен выглядеть следующим образом:
def new_comment(user:)
@greeting = "Hi"
mail to: user.email
end
Обратите внимание, что теперь метод принимает именованный аргумент user
. Это изменение избавляет от ошибки, поскольку теперь UserMailer
сможет получать информацию о пользователе, которому будут отправлены уведомления.
3. Проверка и тестирование
После внесения изменений, убедитесь в том, что все работает корректно, запустив ваш код снова:
CommentNotifier.with(record: Comment.last, message: "New post").deliver(User.last)
Это должно сработать корректно, при условии что User.last
возвращает валидного пользователя с валидным адресом электронной почты.
4. Заключение
Ошибки, связанные с параметрами методов, бывают распространены в случаях, когда конфигурация вызова метода не совпадает с его определением. Убедитесь, что каждый метод, который вы используете в своём проекте, соответствует параметрам, ожидаемым при вызове. Это позволит избежать подобных проблем в будущем.
Также рекомендуем вам использовать отладочные инструменты, такие как puts
или logger
, чтобы отслеживать передаваемую информацию и ловить возможные проблемы на ранних стадиях. Таким образом, ваша система уведомлений станет надежной и устойчивой к ошибкам.