Ruby on Rails:使用simple_form和mail_form发送带附件邮件失败求助
嘿,我来帮你搞定这个邮件附件的问题!你现在能收到邮件但看不到附件,还显示一堆#ActionDispatch::Http::UploadedFile的对象信息,核心原因是mail_form不会自动处理上传的文件对象,得咱们手动配置一下。咱们一步步来改:
第一步:修正你的MailForm Model
首先要在Model里明确标记文件属性为附件,并且告诉mail_form要把它添加到邮件里。修改后的Model代码应该是这样:
class ContactForm < MailForm::Base attribute :name, validate: true attribute :email, validate: /\A([\w\.%\+\-]+)@([\w\-]+\.)+([\w]{2,})\z/i attribute :message # 关键:给file属性加上attachment: true,声明这是一个附件 attribute :file, attachment: true def headers { subject: "新的联系表单提交", to: "你的目标邮箱@example.com", from: %("#{name}" <#{email}>) } end # 重写attachments方法,返回要添加的文件对象 def attachments file.present? ? [file] : [] end end
这里的attachment: true是核心,它告诉mail_form这个字段是文件附件;而重写attachments方法则是把上传的文件对象传递给邮件系统。
第二步:确保Controller允许file参数
你的Controller必须明确允许file参数被提交,不然上传的文件会被过滤掉。检查一下你的参数白名单:
class ContactsController < ApplicationController def new @contact_form = ContactForm.new end def create @contact_form = ContactForm.new(contact_form_params) if @contact_form.deliver redirect_to root_path, notice: "邮件发送成功!" else render :new end end private def contact_form_params # 一定要把:file加到允许的参数列表里 params.require(:contact_form).permit(:name, :email, :message, :file) end end
第三步:确认Simple Form的文件字段渲染正确
在你的表单视图里,要确保文件字段被渲染成正确的<input type="file">,Simple Form的写法是这样:
<%= simple_form_for @contact_form, url: contacts_path do |f| %> <%= f.input :name %> <%= f.input :email %> <%= f.input :message %> <!-- 指定as: :file来渲染文件上传框 --> <%= f.input :file, as: :file %> <%= f.button :submit, "发送邮件" %> <% end %>
不用担心表单的multipart属性,Simple Form在检测到文件字段时会自动给form标签加上enctype="multipart/form-data",这是上传文件必须的。
额外优化:让邮件内容显示文件名而不是对象地址
之前你看到的#ActionDispatch::Http::UploadedFile:0x00007fc9094557c0是因为mail_form默认把属性的to_s结果显示在邮件里。如果想显示文件名,可以自定义邮件内容,比如在Model里重写body方法:
class ContactForm < MailForm::Base # ... 其他代码 ... def body <<~CONTENT 姓名:#{name} 邮箱:#{email} 消息:#{message} 文件:#{file&.original_filename || '无'} CONTENT end end
这样邮件里就会显示上传文件的原始文件名,而不是一堆看不懂的对象地址啦。
内容的提问来源于stack exchange,提问作者Fred
相关产品推荐
相关产品推荐

