如何获取我的Rails应用程序的基本URL(例如http://localhost:3000)?

9

我正在使用Paperclip让用户上传文件,然后我想发送一封电子邮件并将文件附加到邮件中。我正在尝试读取文件并将其作为附件添加,如下所示:

# models/touchpoint_mailer.rb
class TouchpointMailer < ActionMailer::Base
  def notification_email(touchpoint)
    recipients "me@myemail.com"
    from "Touchpoint Customer Portal <portal@touchpointclients.com>"
    content_type "multipart/alternative"
    subject "New Touchpoint Request"
    sent_on Time.now
    body :touchpoint => touchpoint

    # Add any attachments the user has included
    touchpoint.assets.each do |asset|
      attachment :content_type => asset.file_content_type,
                 :body => File.read(asset.url)
    end
  end
end

这让我遇到了以下错误:No such file or directory - /system/files/7/original/image.png?1254497688,调用 File.read 时出现堆栈跟踪。当我访问 show.html.erb 页面并点击像这样的图像链接http://localhost:3000/system/files/7/original/image.png?1254497688 时,图像可以正常显示。

我该如何解决这个问题?

4个回答

22
通常root_url应提供此信息。
但是,File.read期望的是文件路径,而不是url。如果您正在生成图像,则应调用生成图像代码并返回生成的图像字节,而不是调用File.read(…)

我不生成它们,我让用户上传并将它们存储在文件系统中。 - Wayne Molina
但是当我通过asset.url方法指定文件路径时,会出现找不到文件的错误;然而,当我链接到它(例如link_to asset.name, asset.url)时,它可以正常工作,我可以查看图像。 - Wayne Molina
嗯,问题似乎是文件名后面添加的字符串,尝试了cwninja说的方法后,我得到了“无效参数”的错误。有没有办法在不添加那些无用字符的情况下获取文件的基本路径? - Wayne Molina
asset.url.gsub(/\?.*/, "") 作为一个快速修复方案? - cwninja
权限被拒似乎是在根目录 (例如 C:\Documents\Wayne\Projects\Portal\) ,但 Rails 能够对该目录执行其他操作。也许这与这是通过邮件程序而不是控制器有关? - Wayne Molina
显示剩余4条评论

4
asset.url 返回文件的URL。通常是/system/classname/xx/xx/style/filename.ext。您可以将其放在image_tag中。
您需要使用asset.path。它返回文件的完整路径,通常是像/home/username/railsapp/public/system/classname/xx/xx/style/filename.ext这样的东西。
希望对您有所帮助。

3
request.env["HTTP_HOST"]

我不知道为什么这一行代码在网络上如此难找。看起来它应该很显眼易找。


它一直运行得很好,直到我尝试在Rails邮件程序中使用它,并遇到了这个“undefined method 'env' for nil:NilClass”,因此它并不适用于所有情况。 - bennett_an
据我所知,在邮件发送器中不存在request对象。这就是为什么您必须明确为主机定义一个值的原因。不确定为什么这一直被投票支持? - wuliwong
这是不安全的!“HTTP_HOST”标头由用户设置,恶意用户在提交请求时可以将其更改为任何内容。这可能意味着密码重置链接可能被发送到别人的服务器,或者图片可能被更改等。不要使用此功能 - Ben Aubin

1

正如ZiggyTheHamster所说:asset.url是在网页上使用的生成的URL(这就是为什么您会得到类Unix的目录斜杠,如评论中所指出的那样)。

asset.path应该为您提供文件的OS感知路径,但即使使用paperclip也不需要它。 Paperclip :: Attachment已经是IOStream。

您只需要像这样使用:body => asset

touchpoint.assets.each do |asset|
  attachment :content_type => asset.file_content_type,
             :body => asset
end

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接