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
表示它是一个关系对象。
与以下问题类似,但需要不同的解决方案
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
表示它是一个关系对象。