使用 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