Ruby 多态关联在本地有效但在 heroku 中无效

Ruby Polymorphic association working locally but not in heroku

与以下问题类似,但需要不同的解决方案

ActionView::Template::Error (undefined method...) Works locally, but not on Heroku

我的多态关联 Address>Account 在本地工作,但是当我将它上传到 Heroku 时,在呈现视图时出现以下错误:

Rendered addresses/show.html.erb within layouts/application (101.1ms)
2016-01-09T03:04:14.947013+00:00 app[web.1]: 
2016-01-09T03:04:14.947015+00:00 app[web.1]: ActionView::Template::Error (undefined method `addressable' for nil:NilClass):
2016-01-09T03:04:14.947016+00:00 app[web.1]:     1: <div id="central">
2016-01-09T03:04:14.947017+00:00 app[web.1]:     2:     <h1><%= @addresses.addressable.try(:name) %></h1> 
2016-01-09T03:04:14.947018+00:00 app[web.1]:     3:     <h5><%= @addresses.addressable_type %> Address </h5>
2016-01-09T03:04:14.947018+00:00 app[web.1]:     4:     <div id="limiter">
2016-01-09T03:04:14.947020+00:00 app[web.1]:   app/views/addresses/show.html.erb:2:in `_app_views_addresses_show_html_erb__1277570398496108107_69968312940660'
2016-01-09T03:04:14.947019+00:00 app[web.1]:     5:     <table class="tbig" align="center" style="width:100%;">
2016-01-09T03:04:14.947021+00:00 app[web.1]: 
2016-01-09T03:04:14.947021+00:00 app[web.1]: 

模型设置如下:

class Account < ActiveRecord::Base
    has_many :addresses, :as => :addressable
    has_many :contacts
end

class Address < ActiveRecord::Base
   belongs_to :addressable, :polymorphic => true 
end

数据库table喜欢:

class CreateTableAddresses < ActiveRecord::Migration
  def change
    create_table :addresses do |t|
    t.string :no    
    t.string :street
    t.string :suburb
    t.string :code
    t.text :details
    t.belongs_to :city
    t.references :addressable, polymorphic: true, index: true
    t.timestamps null: false    
    end
  end
end

class CreateTableAccounts < ActiveRecord::Migration
    def change
     create_table :accounts do |t|
     t.text :name
     t.string :no
     t.string :site
     t.string :email
     t.string :phone1
     t.string :phone2
     t.text :details
     t.timestamps null: false
     end
    end
 end

来自 show_accounts

时收到错误的地址视图
<div id="central">
    <h1><%= @addresses.addressable.try(:name) %></h1> 
    <h5><%= @addresses.addressable_type %> Address </h5>
    <div id="limiter">
    <table class="tbig" align="center" style="width:100%;">
    <col width="50%">
    <col width="50%">
    <tr><th colspan="2" class="bottom">Address Details</th></tr>    
        <tr class="odd">
        <td class="left">Address System ID: </td>
        <td class="right output"> <%= @addresses.id %> </td>
    </tr>
        <tr class="even">
        <td class="left">Number: </td>
        <td class="right output"> <%= @addresses.no %> </td>
    </tr>
        <tr class="odd">
        <td class="left">Street: </td>
        <td class="right output"><%= @addresses.street %></td>
    </tr>
        <tr class="even">
        <td class="left">Suburb:</td>
        <td class="right output"><%= @addresses.suburb %></td>
    </tr>
        <tr class="odd">
        <td class="left">Post Code: </td>
        <td class="right output"><%= @addresses.code %></td>
    </tr>
        <tr class="even">   
        <td colspan="2" class="bottom"> <%= @addresses.details %></td>     </tr>
        <tr><th colspan="2" class="bottom"></th></tr>
    </table>
<div id="menu">
<ul class="menu">
    <!-- Access Check - Edit Address -->
    <% if Accessrule.find_by(role_id: current_user.role_id, workspace:2).try(:canupdate?) %>
    <li> <%= link_to (image_tag("address_edit.png", :width => "70%")), edit_address_path %>
    <br /><%= link_to "Edit Address", edit_address_path %></li>
    <% end %>

    <!-- back Accounts -->
    <li> <%= link_to (image_tag("address_back.png", :width => "70%")),  @addresses.addressable  %>
    <br /><%= link_to "Back", @addresses.addressable %></li>
    </ul>
 </div>
 </div>

和地址控制器:

class 地址控制器 < 应用程序控制器 before_action :logged_in_user

def address_params
    params.require(:address).permit(:id, :no, :street, :suburb, :code, :details, :city_id, :addressable_type, :addressable_id)
end


def new
    if Accessrule.find_by(role_id: current_user.role_id, workspace:3).try(:canwrite?)
    @logs = Log.create(user_id: current_user.id , role_id: current_user.role_id, workspace_id:3, action:"New")
        @addresses = Address.new(:addressable_type => params[:addressable_type],:addressable_id => params[:addressable_id])
    else
    @logs = Log.create(user_id: current_user.id , role_id: current_user.role_id, workspace_id:3, action:"New !Access Denied! ")
    flash[:notice] = "You don't have access to create Addresses."
    redirect_to :back
    end
end

def create
    if Accessrule.find_by(role_id: current_user.role_id, workspace:3).try(:canwrite?)
    @logs = Log.create(user_id: current_user.id , role_id: current_user.role_id, workspace_id:3, action:"Create", details: address_params)
        @address = Address.new(address_params)
        if @address.save
        flash[:notice] = 'Address Saved'
        redirect_to @address.addressable
        else
        render "new"
        end
    else
    @logs = Log.create(user_id: current_user.id , role_id: current_user.role_id, workspace_id:3, action:"Create !Access Denied! ")
    flash[:notice] = "You don't have access to create Addresses."
    redirect_to :back
    end
end


def edit
    if Accessrule.find_by(role_id: current_user.role_id, workspace:3).try(:canupdate?)
    @logs = Log.create(user_id: current_user.id , role_id: current_user.role_id, workspace_id:3, action:"Edit", details: params[:id])
        @addresses = Address.find(params[:id])
    else
    @logs = Log.create(user_id: current_user.id , role_id: current_user.role_id, workspace_id:3, action:"Edit !Access Denied! ", details: params[:id])
    flash[:notice] = "You don't have access to edit Addresses."
    redirect_to :back
    end
end

def update
    if Accessrule.find_by(role_id: current_user.role_id, workspace:3).try(:canupdate?)
    @logs = Log.create(user_id: current_user.id , role_id: current_user.role_id, workspace_id:3, action:"Update", details: address_params)
        @accounts = Account.all
        @addresses = Address.find(params[:id])
        if @addresses.update_attributes(address_params)
        redirect_to @address.addressable
            flash[:notice] = 'Account Updated'
        else 
        render "edit"
        flash[:error]
        end
    else
    flash[:notice] = "You don't have access to edit Addresss."
    redirect_to back
    end
end

def show
    if Accessrule.find_by(role_id: current_user.role_id, workspace:3).try(:canread?)
    @logs = Log.create(user_id: current_user.id , role_id: current_user.role_id, workspace_id:3, action:"View", details: params[:id])
        @addresses = Address.find(params[:id])
    else
    @logs = Log.create(user_id: current_user.id , role_id: current_user.role_id, workspace_id:3, action:"View !Access Denied! ", details: params[:id])
    flash[:notice] = "You don't have access to view Addresss."
    redirect_to back
    end
end

def destroy
    if Accessrule.find_by(role_id: current_user.role_id, workspace:3).try(:candelete?)
        @addresses = Address.find(params[:id])
        @logs = Log.create(user_id: current_user.id , role_id: current_user.role_id, workspace_id:3, action:"Delete", details: params[:id])
        @addresses.destroy
        redirect_to :back
        flash[:notice] = 'Address Deleted'
    else
    flash[:notice] = "You don't have access to delete Addresss."
    redirect_to :back
        end
end


    # Before Filters
    # Confirms if User is logged-in
    def logged_in_user
     unless logged_in?
     flash[:danger] = "Please log in."
     redirect_to root_path
     end
    end
end

您的协会与此处的错误完全无关。始终查看整个错误消息,尤其是 for nil:NilClass。问题是您的 @addresses 给出了 nil,这可能在搜索数据库中不存在的记录时发生:

@addresses = Address.find(params[:id]) # Can return nil

除此之外 - 你的变量名很混乱。当期望单个对象(不是集合)时,请使用单数 address,复数 addresses 表示它是一个关系对象。