Host ausente para o link! Forneça: parâmetro do host ou defina default_url_options [: host]

183

Estou pesquisando no Google há cerca de 90 minutos e ainda não tenho uma resposta para isso. Onde eu coloco default_url_options? Eu já o configurei para config.action_mailer.default_url_optionsresolver esse mesmo bug em outro lugar, mas agora estou recebendo esse erro ao tentar usar um auxiliar de URL dentro de uma especificação do RSpec. Não tenho idéia de onde ele espera que default_url_options seja definido.

 Failure/Error: listing_url(listing).should match(/\/\d+-\w+$/)
 RuntimeError:
   Missing host to link to! Please provide :host parameter or set default_url_options[:host]
 # ./spec/routing/listing_routing_spec.rb:9:in `block (3 levels) in <top (required)>'

Esse código não tem nada a ver com e-mails / ActionMailer, apenas precisa de um URL em vez de um caminho.

Alguma ideia?

d11wtq
fonte
Qual é o host, afinal?
precisa saber é o seguinte

Respostas:

260

Você precisa adicionar a seguinte linha em todos os ambientes:

config.action_mailer.default_url_options = { :host => "yourhost" }

Dessa forma, ele pode funcionar em todos os ambientes e pode ser diferente de ambiente para ambiente. Por exemplo:

development.rb

config.action_mailer.default_url_options = { :host => "dev.yourhost.com" }

test.rb

config.action_mailer.default_url_options = { :host => "test.yourhost.com" }

production.rb

config.action_mailer.default_url_options = { :host => "www.yourhost.com" }
Carlos Castillo
fonte
16
Além disso, certifique-se de reiniciar o servidor Rails após adicionar isso. Os arquivos em config / não são recarregados automaticamente.
Stenerson
3
Eu fiz muito parecido com isso e definir a opção default_url_option para action_mailer não ajudará. O caso de utilização é semelhante ao seguinte: Rails.application.routes.url_helpers.message_image_url (2)
Boti
1
Fez isso; com ou sem www ... prefixando o nome do host em produção, ainda recebi o mesmo erro. Adicionada a rota por @ d11wtq e funcionou. Existe alguma alteração no Rails4 que causou esse comportamento? Eu nunca vi isso antes da atualização, e apenas em um determinado envio de email (automatizado), desde então.
JosephK
Posso confirmar que isso não funciona nos meus projetos do Rails 4. Configurá-lo em rotas simplesmente não é uma opção.
b1nary
4
Não funciona no Rails 5. Adicionado default_url_options Rails.application.config.action_mailer.default_url_optionsembora e que fez o truque, como sugerido por outro comentarista
BooBailey
74
Your::Application.routes.draw do
  default_url_options :host => "example.com"

  # ... snip ...
end

Em algum lugar em routes.rb:)

d11wtq
fonte
35
Não é muito bom se você tem muitos ambientes diferentes com URLs diferentes
Neil Middleton
2
Sim, o que você faz se tiver vários domínios env?
28512 we werrowski
Presumivelmente, você só especificá-lo para cada URL em vez disso, quer no mapa de rota, ou na invocação ajudante url: listing_url(listing, :host => "whatever.com").
d11wtq
14
No arquivo de configuração de cada ambiente respectivo, adiciono esta opção personalizada: config.domain = 'staging.myapp.com'(é claro, substitua o nome de domínio correto por cada ambiente). Então, routes.rbeu estou livre para usar default_url_options host: Rails.application.config.domaine funcionará em qualquer ambiente. De nada.
Prank Thananart
10
Uma abordagem melhor seria, dentro do arquivo de rotas, faça o seguinte: default_url_options Rails.application.config.action_mailer.default_url_options.
Siannopollo 28/03
42

O host deve ser especificado no arquivo de configuração de cada ambiente. Por exemplo:

config/environments/development.rb

Veja esta pergunta e esta pergunta .

nickh
fonte
4
Obrigado, IMHO esta é uma resposta melhor do que a resposta que usos Routes.draw
joelparkerhenderson
1
Esta resposta não ajuda ao usar domínios diferentes e soluciona outros problemas.
21712 Ryan
1
@ Ryan você pode simplesmente usar o ambiente vars de corrigir isso
courtsimas
35

Defina default_url_optionspara usar o seu action_mailer.default_url_options.

Em cada um dos seus arquivos de ambiente (por exemplo development.rb, production.rb, etc.) você pode especificar o default_url_optionsuse para action_mailer:

config.action_mailer.default_url_options = { host: 'lvh.me', port: '3000' }

No entanto, eles não estão definidos para MyApp:Application.default_url_options:

$ MyApp::Application.config.action_mailer.default_url_options
#=> {:host=>"lvh.me", :port=>"3000"}

$ MyApp::Application.default_url_options
#=> {}

É por isso que você está recebendo esse erro em qualquer coisa fora dele ActionMailer.

Você pode configurar seu aplicativo é default_url_optionsusar o que você definiu para action_mailerno arquivo de ambiente adequado ( development.rb, production.rb, etc.).

Para manter o mais seco possível, faça isso no seu config/environment.rbarquivo, para fazer isso apenas uma vez:

# Initialize the rails application
MyApp::Application.initialize!

# Set the default host and port to be the same as Action Mailer.
MyApp::Application.default_url_options = MyApp::Application.config.action_mailer.default_url_options

Agora, quando você inicializar seu aplicativo, todo o seu aplicativo default_url_optionscorresponderá ao seu action_mailer.default_url_options:

$ MyApp::Application.config.action_mailer.default_url_options
#=> {:host=>"lvh.me", :port=>"3000"}

$ MyApp::Application.default_url_options
#=> {:host=>"lvh.me", :port=>"3000"}

Dica de chapéu para @pduersteler por me levar por esse caminho.

Joshua Pinter
fonte
2
Configurar o config/environment.rbque você descreveu foi a chave para fazer meu mailer funcionar no console. Obrigado!
Eric D. Fields
@ EricD.Fields De nada, Eric! Acho isso tão útil que acho que deve ser incorporado ao núcleo do Rails.
Joshua Pinter
Isso seria Rails.application.default_url_options = Rails.application.config.action_mailer.default_url_optionspara o Rails 5.2+ #
Sandro L
Obrigado, @SandroL! Ainda estamos no Rails 4.2, portanto ainda não testamos em versões posteriores.
Joshua Pinter
Algumas pessoas recomendam isso. Acho que as pessoas tendem a ter action_mailer.default_url_options já configuradas por razões históricas, mas não é mais lógico definir isso com base em application.default_url_options, e não o contrário? Por que envolver uma referência falsa de mala direta ao configurar como os links do site funcionam?
Harry Wood
24

Quando você usa qualquer listing_urlmétodo, o URL completo será retornado (não um relativo, como normal). É por isso que o Rails está solicitando o host para calcular a URL inteira.

Como você pode dizer aos trilhos o host? Você pode fazer isso de várias maneiras:

1.Adicionando esta opção a cada ambiente:

[/config/development.rb]
config.action_mailer.default_url_options = { host: "localhost:3000" }
[/config/test.rb]
config.action_mailer.default_url_options = { host: "localhost:3000" }
[/config/production.rb]
config.action_mailer.default_url_options = { host: "www.example.com" }

NOTA: Se você estiver trabalhando dentro de um mecanismo de trilhos, lembre - se de fazer o mesmo com seu aplicativo fictício dentro dos testes de mecanismo: path_to_your_engine/test/dummy/config/environments/*porque quando você testa o mecanismo, é contra isso que os trilhos estão testando.

2. Adicione a opção de host ao método foo_url da seguinte maneira:

listing_url(listing, host: request.host) # => 'http://localhost:3000/listings/1'

Saída 3.Não o anfitrião com a opção:only_path to true .

listing_url(listing, only_path: true ) # => '/listings/1'   

IMHO Eu não vejo o ponto neste, porque neste caso eu usaria o listing_pathmétodo

ivanxuu
fonte
O passo 1 sempre funciona para mim e hoje, usando a jóia refinery-cms, apenas o passo 2 me salva. Obrigado pelo comentário.
lucianosousa
15

Engraçado, essa configuração config.action_mailer.default_url_optionsnão ajuda para mim. Além disso, mexer com configurações independentes do ambiente em lugares que eu senti que não pertencem não foi satisfatório para mim. Além disso, eu queria uma solução que funcionasse ao gerar URLs em trabalhadores sidekiq / resque.

Minha abordagem até agora, que aborda config/environments/{development, production}.rb:

MyApp::Application.configure do
    # Stuff omitted...

    config.action_mailer.default_url_options = {
      # Set things here as usual
    }
end

MyApp::Application.default_url_options = MyApp::Application.config.action_mailer.default_url_options

Isso funciona para mim em trilhos> = 3.2.x.

pduersteler
fonte
1
Isso e somente isso funcionou para que o remetente incluísse a URL, mas quebra outras funções link_to no meu aplicativo.
1
Grande pensamento, @pduesteler! Na verdade, dei um passo adiante e consegui adicionar apenas uma linha no config/environment.rbarquivo para fazer isso. E uma resposta adicionada que entra em detalhes: stackoverflow.com/a/48529627/293280 Obrigado por me indicar nessa direção.
Joshua Pinter
9

Rails.application.routes.default_url_options[:host]= 'localhost:3000'

No developemnt.rb / test.rb, pode ser mais conciso da seguinte maneira:

Rails.application.configure do
  # ... other config ...

  routes.default_url_options[:host] = 'localhost:3000'
end
Derek Fan
fonte
7

Você sempre pode passar o host como um parâmetro para o auxiliar de URL:

listing_url(listing, host: request.host)
Undistraction
fonte
Nota: Você também pode adicionar uma portalisting_url(listing, host: request.host, port: 3000)
drhenner
Mas e se você não tiver o contexto de solicitação? Como na maioria das coisas além de um controlador?
precisa saber é o seguinte
1

Eu tive esse mesmo erro. Escrevi tudo corretamente, incluindo a Listagem 10.13 do tutorial.

Rails.application.configure do
.
.
.
config.action_mailer.raise_delivery_errors = true
config.action_mailer.delevery_method :test
host = 'example.com'
config.action_mailer.default_url_options = { host: host }
.
.
.
end

obviamente com "example.com" substituído pelo meu URL do servidor.

O que eu havia encoberto no tutorial era esta linha:

Após reiniciar o servidor de desenvolvimento para ativar a configuração ...

Portanto, a resposta para mim foi desligar e ligar novamente o servidor.

Okomikeruko
fonte
1

vá para config / environment / test.rb

Rails.application.routes.default_url_options [: host] = 'localhost: 3000'

milad rahmani
fonte
2
A resposta precisa de mais informações. Por favor, descreva o que você está realmente propondo como solução.
Levi Roberts
1
Aqui estão algumas dicas úteis sobre como responder . Acho-os úteis para se referir.
Garrett Motzner
1

apenas no caso de alguém encontrar isso procurando erros relacionados ao ActiveStorage:

se você tiver uma ação de controlador na qual deseja gerar URLs de upload, etc, com o serviço de disco local (provavelmente no ambiente de teste), precisará include ActiveStorage::SetCurrentdo controlador para permitir blob.service_url_for_direct_uploadque funcione corretamente.

phoet
fonte
Obrigado! Usar isso fora de um controlador (mutação de upload direto do GraphQL) teve que ajustá-lo um pouco, mas funciona. Eu estive procurando por isso, obrigado novamente @phoet :)
Stan
0

Adicionar o default_url em rotas não é a solução certa, embora funcione em alguns casos.

Você deve definir o default_url em cada ambiente (desenvolvimento, teste, produção).

Você precisa fazer essas alterações.

    config/environments/development.rb
     config.action_mailer.default_url_options = 
      { :host => 'your-host-name' }  #if it is local then 'localhost:3000'

 config/environments/test.rb
      config.action_mailer.default_url_options = 
      { :host => 'your-host-name' }  #if it is local then 'localhost:3000'

  config/environments/development.rb
     config.action_mailer.default_url_options = 
      { :host => 'your-host-name' }  #if it is local then 'localhost:3000'
Prabhakar Undurthi
fonte
0

A resposta acima não funcionou para mim, pelo menos não como eu queria. Eu percebi config.action_mailer.default_url_options = { host: "localhost", port: 3000 } depois de instalar o dispositivo. Espero que ajude alguém com o mesmo problema.

Ahmed J.
fonte