Ошибка RuntimeError default_url_options host и root_url (с поддоменом)

#ruby-on-rails-3 #subdomain #actionmailer #urlhelper

#ruby-on-rails-3 #поддомен #actionmailer #urlhelper

Вопрос:

У каждого пользователя моего приложения есть пользовательский URL (через поддомен), хранящийся в базе данных.

Мой запрос прост, я хотел бы отправить «URL пользователя» через канал json, вот так:

 {user_name: "vincent", :user_url: "vincent.my_app.com"}
  

для этого я должен перезаписать функцию as_json пользовательской модели:

 def as_json(options={})
    {
        :user_name: self.name,
        :user_url: root_url(:subdomain => self.subdomain)
    }
end
  

У меня есть этот дополнительный модуль (который отлично работает и не является реальной проблемой):

 module SubdomainHelper
def with_subdomain(subdomain)
    subdomain = (subdomain || "")
    subdomain  = "." unless subdomain.empty?
    host = ActionMailer::Base.default_url_options[:host]
    [subdomain, host].join
end

def url_for(options = nil)
    if options.kind_of?(Hash) amp;amp; options.has_key?(:subdomain)
        options[:host] = with_subdomain(options.delete(:subdomain))
    end
    super
end
end
  

Но когда я получаю канал json, у меня возникает эта ошибка:

 RuntimeError (Missing host to link to! Please provide :host parameter or set default_url_options[:host]):
  

указывает на метод «as_json» пользовательской модели.

конечно, каждая среда реализует default_url_options в dev.rb:

 config.action_mailer.default_url_options = {:host => 'my_app:3000'}
  

Я не понимаю, почему и как я это исправляю. Пожалуйста, помогите мне.

Ответ №1:

У меня была похожая проблема. Каким-то образом это, похоже, было связано с url_helper actionpack и именем моего поля. Похоже, проблема с именами полей, оканчивающимися на * _url. Не совсем понимаю, почему, но у меня было поле с именем login_url, которое я переименовал в login_uri (обратите внимание на изменение с l на i), и это устранило мою проблему.

Ответ №2:

Чтобы использовать помощник URL root_path в вашей модели, я предполагаю, что вы смешиваете Rails.application.routes.url_helpers или что-то подобное. Эти помощники всегда создают URL-адреса, ссылающиеся default_url_options . ActionController определяет эти параметры по умолчанию из текущего запроса. config.action_mailer.default_url_options предназначена только для почтовых программ, у которых нет запроса на интуитивное определение значений по умолчанию, не для использования в моделях. Представления делегируются контроллеру / почтовой программе. Каждый класс, в котором используются эти помощники, должен предоставлять default_url_options , но, как правило, переопределять его — плохая идея. Укажите URL-адрес из контроллера, почтовой программы или представления.

Если вам действительно нужно, в вашей модели: delegate :default_url_options, to: ActionMailer::Base