使用 Sendgrid Rails Heroku 发送电子邮件时如何获取或访问不同的模型属性
How can I grab or access different model attribute when I send email using Sendgrid Rails Heroku
我正在使用设计和脚手架教科书。
我喜欢实施我的策略。
当买家点击@textbook.title -> 买家可以向@textbook 的卖家发送电子邮件。
我让每个模型都有 'user_email' 列
因此,每当卖家创建@textbook 时,current_user.email 会自动保存到@textbook.user_email.
我只是不知道如何获取卖家的 user_email 并发送电子邮件。
我关注
教材型号:
class Textbook < ActiveRecord::Base
belongs_to :user
validates :title, :presence => true
validates :subject, :presence => true
validates :price, :presence => true
validates :offer, :presence => false
validates :created_at, :presence => false
validates :user_email, :presence => true
validates :description, :presence => true
end
我不确定这个模型语法是否适合主题 current_user.email
联系人型号:
class Contact < MailForm::Base
attribute :name, :validate => true
attribute :current_user.email, :validate => /\A([\w\.%\+\-]+)@([\w\-]+\.)+([\w]{2,})\z/i
attribute :message, :validate => true
def headers
{
:subject => "I like to buy #{@textbook.id.title}",
:to => "@textbook.id.user_email",
:from => %(<#{email}>)
}
end
end
我的详细问题是:
如果当买家在特定教科书内时用户单击 'contact',它会将用户链接到 textbook#show。下面是用户点击 'contact'.
时的表单
如何确保下面的视图访问正确的 textbook.id 或 textbook.title?
<h1> Contact to the Seller </h1>
<div>
<%=form_for @contact do |f|%>
<h3>Send email for: <%=@textbook.id.title%> </h3>
<%= f.label :message %><br>
<%= f.text_area :message, as: :text %><br>
<%=f.submit 'Send message', class: 'button' %>
<%end%>
</div>
特别是,我不知道如何处理来自不同视图中不同模型的抓取属性。
提前致谢!
-!#-!#-!#-!#-!#-!#-!#-!#-!#-!#-!#-!#-!#-!#-!# -!#-!
更新 1:
我有这样的联系人控制器:
class ContactsController < ApplicationController
def new
@contact = Contact.new
end
def create
@contact = Contact.new(params[:contact])
#@contact.request = request
if @contact.deliver
flash[:success] = "Email sent."
else
flash[:alert] = "Cannot send an email."
render :new
end
end
end
我刚刚编辑了我的 'class Contact < MailForm::Base'
class Contact < MailForm::Base
attribute :name, :validate => true
attribute :email, :validate => /\A([\w\.%\+\-]+)@([\w\-]+\.)+([\w]{2,})\z/i
attribute :message, :validate => true
def headers
{
:subject => "I like to buy #{textbook.title}",
:to => "@textbook.user_email",
:from => %(<#{current_user.email}>)
}
end
结束
但是我得到了错误:
NameError in ContactsController#create
undefined local variable or method `textbook' for #<Contact:0x007fbac641be40>
Extracted source (around line #8):
def headers
{
:subject => "I like to buy #{textbook.title}",
:to => "@textbook.user_email",
:from => %(<#{current_user.email}>)
}
@zeiv 我修复了 textbook.title -> @textbook.title
我收到另一个错误。
NoMethodError in ContactsController#create
undefined method `title' for nil:NilClass
def headers
{
:subject => "I like to buy #{@textbook.title}",
:to => "@textbook.user_email",
:from => %(<#{current_user.email}>)
}
我有views/textbooks.html.erb:
<div class="container">
<p>
<h3><strong>Title:</strong>
<%= @textbook.title %></h3>
</p>
<p>
<strong>Subject:</strong>
<%= @textbook.subject %>
</p>
<p>
<strong>Price:</strong>
$<%= @textbook.price %>
</p>
<p>
<strong>Accept Offer:</strong>
<%if @textbook.offer == true%>
<%='Yes'%>
<%else%>
<%='No'%>
<%end%>
</p>
<p>
<strong>Description:</strong>
<pre><%= @textbook.description %></pre>
</p>
<p>
<strong>Image:</strong>
<pre><%= image_tag @textbook.thumbnail.url(:medium) %></pre>
</p>
<p>
<strong>Created on:</strong>
<%= @textbook.created_at.strftime("%d %b. %Y") %>
</p>
<p>
<%= link_to 'Contact', new_contact_path %>
</p>
<%if @textbook.user_email == current_user.email %>
<%= link_to 'Edit', edit_textbook_path(@textbook) %> |
<%= link_to 'Back to list', textbooks_path %>
<%else %>
<%= link_to 'Back to list', textbooks_path %>
<%end%>
我有 textbooks_controller:
class TextbooksController < ApplicationController
before_action :set_textbook, only: [:show, :edit, :update, :destroy]
#before_action :set_textbook, only: [:show]
#before_action :authorize_resource!, except: [:new, :index, :show]
# GET /textbooks
# GET /textbooks.json
def index
#@textbooks = Textbook.all
@textbooks = Textbook.all.order(created_at: :desc).paginate(page: params[:page], per_page: 10)
#@textbooks = Textbook.paginate(:page => params[:page], :per_page => 10)
end
# GET /textbooks/1
# GET /textbooks/1.json
def show
end
我有 config/routes:
resources :textbooks
resources :contacts, only: [:new, :create]
devise_for :users
此时此刻我耙路线的时候 4/17 5:05pm
new_textbook GET /textbooks/new(.:format) textbooks#new
edit_textbook GET /textbooks/:id/edit(.:format) textbooks#edit
textbook GET /textbooks/:id(.:format) textbooks#show
PATCH /textbooks/:id(.:format) textbooks#update
PUT /textbooks/:id(.:format) textbooks#update
DELETE /textbooks/:id(.:format) textbooks#destroy
contacts POST /contacts(.:format) contacts#create
new_contact GET /contacts/new(.:format) contacts#new
更新 2 -!#-!#-!#-!#-!#-!#-!#-!#-!#-!#-!#-!#-!#-!#- !#-!#-!
以下是 2016 年 4 月 17 日之后的 11:00pm
@zeiv 我照你说的做了。
但是当我点击 views/textbooks/show.html.erb
中的 'contact' 按钮时仍然出现错误
#views/textbooks/show.html.erb
<p>
<%= link_to 'Contact', new_contact_textbook_path %>
</p>
我的 routes.rb 现在有:
Rails.application.routes.draw do
resources :textbooks do
member do
get 'contact', to: 'textbooks#new_contact', as: 'new_contact'
post 'contact', to: 'textbooks#send_contact', as: 'send_contact'
end
end
rake 路线现在有:
Prefix Verb URI Pattern Controller#Action
new_contact_textbook GET /textbooks/:id/contact(.:format) textbooks#new_contact
send_contact_textbook POST /textbooks/:id/contact(.:format) textbooks#send_contact
textbooks GET /textbooks(.:format) textbooks#index
POST /textbooks(.:format) textbooks#create
new_textbook GET /textbooks/new(.:format) textbooks#new
edit_textbook GET /textbooks/:id/edit(.:format) textbooks#edit
textbook GET /textbooks/:id(.:format) textbooks#show
PATCH /textbooks/:id(.:format) textbooks#update
PUT /textbooks/:id(.:format) textbooks#update
DELETE /textbooks/:id(.:format) textbooks#destroy
我得到的错误是这样的:
NoMethodError in Textbooks#new_contact
undefined method `id' for nil:NilClass
Extracted source (around line #4):
<div>
Texbook id is: <%= @textbook.id %>
</div>
我是运行 heroku local 错误显示:
10:56:13 PM web.1 | Rendered textbooks/new_contact.html.erb within layouts/application (2.0ms)
10:56:13 PM web.1 | Completed 500 Internal Server Error in 7ms (ActiveRecord: 0.1ms)
10:56:13 PM web.1 | ActionView::Template::Error (undefined method `id' for nil:NilClass):
10:56:13 PM web.1 | 1: <h1> contact seller! - working? </h1>
10:56:13 PM web.1 | 2:
10:56:13 PM web.1 | 3: <div>
10:56:13 PM web.1 | 4: Texbook id is: <%= @textbook.id %>
10:56:13 PM web.1 | 5: </div>
基本上您需要做的是以这样一种方式编写您的邮件程序和控制器,以便将您想要的所有信息传递给邮件程序。因此,如果您希望将 Textbook 模型的实例传递给邮件程序,则需要从发送电子邮件的控制器执行此操作。您可能希望将您的联系人控制器路由嵌套在您的教科书路由中以帮助您。或者,与其拥有一个完整的联系人控制器,不如在教科书控制器中拥有一个联系人 action。
# route.rb
...
resources :textbooks do
member do
get "contact", to: "textbooks#new_contact", as: "new_contact"
post "contact", to: "textbooks#send_contact", as: "send_contact"
end
end
这将为您提供类似 /textbook/24/contact
的路线。 member do
表示路由适用于模型的单个实例而不是整个集合,因此您需要在调用它们的助手时指定您指的是哪本教科书:new_contact_textbook_path(@textbook.id)
.
所以在你的 Textbook 控制器中,你会这样做:
# textbooks_controller.rb
before_action :set_textbook, only: [:show, :edit, :update, :destroy, :new_contact, :send_contact]
...
def new_contact
# We are NOT doing Contact.new here
# Only put logic here that you need to display the form
end
def send_contact
message = params[:message]
if Contact.send_contact(@textbook, current_user, message).deliver
flash[:success] = "Email sent."
redirect_to @textbook
else
flash[:alert] = "There was a problem sending the email."
render :new_contact
end
end
然后将您的 new_contact.html.erb
文件与其他教科书视图放在一起。
<h1> Contact to the Seller </h1>
<div>
<%= form_tag send_contact_textbook_path(@textbook.id) do %>
<h3>Send email for: <%=@textbook.title%> </h3>
<%= label_tag :message, "Type your message:" %><br>
<%= text_area_tag :message %><br>
<%= submit_tag 'Send message', class: 'button' %>
<%end%>
</div>
请注意,我使用的是 form_tag
而不是 form_for
,因为我们没有要传递给它的联系人对象。 (也就是说,Contact 不是模型。它是邮寄者。)
您的邮件将看起来像这样:
class Contact < ApplicationMailer
def send_contact(textbook, current_user, message)
@textbook = textbook
@current_user = current_user
@message = message
mail(
from: "#{@current_user.name} <#{@current_user.email}>",
to: @textbook.user.email,
subject: "I would like to buy #{@textbook.title}",
reply_to: @current_user.email,
)
end
end
最后,将您的 template/view 放入 /app/views/contact/send_contact.html.erb
:
<!DOCTYPE html>
<html>
<head>
<meta content='text/html; charset=UTF-8' http-equiv='Content-Type' />
</head>
<body>
<h1><%= @current_user.name %> is wondering about <%= @textbook.title %>:</h1>
<p><%= @message %></p>
</body>
</html>
应该就可以了!尽管您可能需要调整一些内容以满足您的需要。另请参阅以下链接以获取更多示例:
Contact Form Mailer in Rails 4
https://sendgrid.com/docs/Integrate/Frameworks/rubyonrails.html
我正在使用设计和脚手架教科书。 我喜欢实施我的策略。 当买家点击@textbook.title -> 买家可以向@textbook 的卖家发送电子邮件。 我让每个模型都有 'user_email' 列 因此,每当卖家创建@textbook 时,current_user.email 会自动保存到@textbook.user_email.
我只是不知道如何获取卖家的 user_email 并发送电子邮件。
我关注
教材型号:
class Textbook < ActiveRecord::Base
belongs_to :user
validates :title, :presence => true
validates :subject, :presence => true
validates :price, :presence => true
validates :offer, :presence => false
validates :created_at, :presence => false
validates :user_email, :presence => true
validates :description, :presence => true
end
我不确定这个模型语法是否适合主题 current_user.email 联系人型号:
class Contact < MailForm::Base
attribute :name, :validate => true
attribute :current_user.email, :validate => /\A([\w\.%\+\-]+)@([\w\-]+\.)+([\w]{2,})\z/i
attribute :message, :validate => true
def headers
{
:subject => "I like to buy #{@textbook.id.title}",
:to => "@textbook.id.user_email",
:from => %(<#{email}>)
}
end
end
我的详细问题是: 如果当买家在特定教科书内时用户单击 'contact',它会将用户链接到 textbook#show。下面是用户点击 'contact'.
时的表单如何确保下面的视图访问正确的 textbook.id 或 textbook.title?
<h1> Contact to the Seller </h1>
<div>
<%=form_for @contact do |f|%>
<h3>Send email for: <%=@textbook.id.title%> </h3>
<%= f.label :message %><br>
<%= f.text_area :message, as: :text %><br>
<%=f.submit 'Send message', class: 'button' %>
<%end%>
</div>
特别是,我不知道如何处理来自不同视图中不同模型的抓取属性。
提前致谢!
-!#-!#-!#-!#-!#-!#-!#-!#-!#-!#-!#-!#-!#-!#-!# -!#-!
更新 1:
我有这样的联系人控制器:
class ContactsController < ApplicationController
def new
@contact = Contact.new
end
def create
@contact = Contact.new(params[:contact])
#@contact.request = request
if @contact.deliver
flash[:success] = "Email sent."
else
flash[:alert] = "Cannot send an email."
render :new
end
end
end
我刚刚编辑了我的 'class Contact < MailForm::Base'
class Contact < MailForm::Base
attribute :name, :validate => true
attribute :email, :validate => /\A([\w\.%\+\-]+)@([\w\-]+\.)+([\w]{2,})\z/i
attribute :message, :validate => true
def headers
{
:subject => "I like to buy #{textbook.title}",
:to => "@textbook.user_email",
:from => %(<#{current_user.email}>)
}
end
结束
但是我得到了错误:
NameError in ContactsController#create
undefined local variable or method `textbook' for #<Contact:0x007fbac641be40>
Extracted source (around line #8):
def headers
{
:subject => "I like to buy #{textbook.title}",
:to => "@textbook.user_email",
:from => %(<#{current_user.email}>)
}
@zeiv 我修复了 textbook.title -> @textbook.title 我收到另一个错误。
NoMethodError in ContactsController#create
undefined method `title' for nil:NilClass
def headers
{
:subject => "I like to buy #{@textbook.title}",
:to => "@textbook.user_email",
:from => %(<#{current_user.email}>)
}
我有views/textbooks.html.erb:
<div class="container">
<p>
<h3><strong>Title:</strong>
<%= @textbook.title %></h3>
</p>
<p>
<strong>Subject:</strong>
<%= @textbook.subject %>
</p>
<p>
<strong>Price:</strong>
$<%= @textbook.price %>
</p>
<p>
<strong>Accept Offer:</strong>
<%if @textbook.offer == true%>
<%='Yes'%>
<%else%>
<%='No'%>
<%end%>
</p>
<p>
<strong>Description:</strong>
<pre><%= @textbook.description %></pre>
</p>
<p>
<strong>Image:</strong>
<pre><%= image_tag @textbook.thumbnail.url(:medium) %></pre>
</p>
<p>
<strong>Created on:</strong>
<%= @textbook.created_at.strftime("%d %b. %Y") %>
</p>
<p>
<%= link_to 'Contact', new_contact_path %>
</p>
<%if @textbook.user_email == current_user.email %>
<%= link_to 'Edit', edit_textbook_path(@textbook) %> |
<%= link_to 'Back to list', textbooks_path %>
<%else %>
<%= link_to 'Back to list', textbooks_path %>
<%end%>
我有 textbooks_controller:
class TextbooksController < ApplicationController
before_action :set_textbook, only: [:show, :edit, :update, :destroy]
#before_action :set_textbook, only: [:show]
#before_action :authorize_resource!, except: [:new, :index, :show]
# GET /textbooks
# GET /textbooks.json
def index
#@textbooks = Textbook.all
@textbooks = Textbook.all.order(created_at: :desc).paginate(page: params[:page], per_page: 10)
#@textbooks = Textbook.paginate(:page => params[:page], :per_page => 10)
end
# GET /textbooks/1
# GET /textbooks/1.json
def show
end
我有 config/routes:
resources :textbooks
resources :contacts, only: [:new, :create]
devise_for :users
此时此刻我耙路线的时候 4/17 5:05pm
new_textbook GET /textbooks/new(.:format) textbooks#new
edit_textbook GET /textbooks/:id/edit(.:format) textbooks#edit
textbook GET /textbooks/:id(.:format) textbooks#show
PATCH /textbooks/:id(.:format) textbooks#update
PUT /textbooks/:id(.:format) textbooks#update
DELETE /textbooks/:id(.:format) textbooks#destroy
contacts POST /contacts(.:format) contacts#create
new_contact GET /contacts/new(.:format) contacts#new
更新 2 -!#-!#-!#-!#-!#-!#-!#-!#-!#-!#-!#-!#-!#-!#- !#-!#-!
以下是 2016 年 4 月 17 日之后的 11:00pm @zeiv 我照你说的做了。 但是当我点击 views/textbooks/show.html.erb
中的 'contact' 按钮时仍然出现错误#views/textbooks/show.html.erb
<p>
<%= link_to 'Contact', new_contact_textbook_path %>
</p>
我的 routes.rb 现在有:
Rails.application.routes.draw do
resources :textbooks do
member do
get 'contact', to: 'textbooks#new_contact', as: 'new_contact'
post 'contact', to: 'textbooks#send_contact', as: 'send_contact'
end
end
rake 路线现在有:
Prefix Verb URI Pattern Controller#Action
new_contact_textbook GET /textbooks/:id/contact(.:format) textbooks#new_contact
send_contact_textbook POST /textbooks/:id/contact(.:format) textbooks#send_contact
textbooks GET /textbooks(.:format) textbooks#index
POST /textbooks(.:format) textbooks#create
new_textbook GET /textbooks/new(.:format) textbooks#new
edit_textbook GET /textbooks/:id/edit(.:format) textbooks#edit
textbook GET /textbooks/:id(.:format) textbooks#show
PATCH /textbooks/:id(.:format) textbooks#update
PUT /textbooks/:id(.:format) textbooks#update
DELETE /textbooks/:id(.:format) textbooks#destroy
我得到的错误是这样的:
NoMethodError in Textbooks#new_contact
undefined method `id' for nil:NilClass
Extracted source (around line #4):
<div>
Texbook id is: <%= @textbook.id %>
</div>
我是运行 heroku local 错误显示:
10:56:13 PM web.1 | Rendered textbooks/new_contact.html.erb within layouts/application (2.0ms)
10:56:13 PM web.1 | Completed 500 Internal Server Error in 7ms (ActiveRecord: 0.1ms)
10:56:13 PM web.1 | ActionView::Template::Error (undefined method `id' for nil:NilClass):
10:56:13 PM web.1 | 1: <h1> contact seller! - working? </h1>
10:56:13 PM web.1 | 2:
10:56:13 PM web.1 | 3: <div>
10:56:13 PM web.1 | 4: Texbook id is: <%= @textbook.id %>
10:56:13 PM web.1 | 5: </div>
基本上您需要做的是以这样一种方式编写您的邮件程序和控制器,以便将您想要的所有信息传递给邮件程序。因此,如果您希望将 Textbook 模型的实例传递给邮件程序,则需要从发送电子邮件的控制器执行此操作。您可能希望将您的联系人控制器路由嵌套在您的教科书路由中以帮助您。或者,与其拥有一个完整的联系人控制器,不如在教科书控制器中拥有一个联系人 action。
# route.rb
...
resources :textbooks do
member do
get "contact", to: "textbooks#new_contact", as: "new_contact"
post "contact", to: "textbooks#send_contact", as: "send_contact"
end
end
这将为您提供类似 /textbook/24/contact
的路线。 member do
表示路由适用于模型的单个实例而不是整个集合,因此您需要在调用它们的助手时指定您指的是哪本教科书:new_contact_textbook_path(@textbook.id)
.
所以在你的 Textbook 控制器中,你会这样做:
# textbooks_controller.rb
before_action :set_textbook, only: [:show, :edit, :update, :destroy, :new_contact, :send_contact]
...
def new_contact
# We are NOT doing Contact.new here
# Only put logic here that you need to display the form
end
def send_contact
message = params[:message]
if Contact.send_contact(@textbook, current_user, message).deliver
flash[:success] = "Email sent."
redirect_to @textbook
else
flash[:alert] = "There was a problem sending the email."
render :new_contact
end
end
然后将您的 new_contact.html.erb
文件与其他教科书视图放在一起。
<h1> Contact to the Seller </h1>
<div>
<%= form_tag send_contact_textbook_path(@textbook.id) do %>
<h3>Send email for: <%=@textbook.title%> </h3>
<%= label_tag :message, "Type your message:" %><br>
<%= text_area_tag :message %><br>
<%= submit_tag 'Send message', class: 'button' %>
<%end%>
</div>
请注意,我使用的是 form_tag
而不是 form_for
,因为我们没有要传递给它的联系人对象。 (也就是说,Contact 不是模型。它是邮寄者。)
您的邮件将看起来像这样:
class Contact < ApplicationMailer
def send_contact(textbook, current_user, message)
@textbook = textbook
@current_user = current_user
@message = message
mail(
from: "#{@current_user.name} <#{@current_user.email}>",
to: @textbook.user.email,
subject: "I would like to buy #{@textbook.title}",
reply_to: @current_user.email,
)
end
end
最后,将您的 template/view 放入 /app/views/contact/send_contact.html.erb
:
<!DOCTYPE html>
<html>
<head>
<meta content='text/html; charset=UTF-8' http-equiv='Content-Type' />
</head>
<body>
<h1><%= @current_user.name %> is wondering about <%= @textbook.title %>:</h1>
<p><%= @message %></p>
</body>
</html>
应该就可以了!尽管您可能需要调整一些内容以满足您的需要。另请参阅以下链接以获取更多示例:
Contact Form Mailer in Rails 4
https://sendgrid.com/docs/Integrate/Frameworks/rubyonrails.html