【问题标题】:Error when passing in nil value on Rails object在 Rails 对象上传递 nil 值时出错
【发布时间】:2016-10-17 00:56:45
【问题描述】:

我有一个用户有投资组合的应用。一个投资组合可以有很多头寸,每个头寸可以有很多变动。

我的作品集展示页面是这样构建的:

<p>
  <strong>Name:</strong>
  <%= @portfolio.name %>
</p>

<h1>Positions</h1>
<div class = 'table'>
<table>
  <thead>
    <tr>
      <th>Name</th>
      <th>Quantity</th>
      <th>Stock</th>
      <th colspan="3"></th>
    </tr>
  </thead>
<tbody id = "positions">
  <%= render @positions %>
</tbody>
</table>
</div>

<h3>New Position</h3>

<%= render 'positions/form' %>

<%= link_to 'Edit', edit_portfolio_path(@portfolio) %> |
<%= link_to 'Back', portfolios_path %>

我的位置部分是建立的:

<tr>
  <td class="col-md-1"><%= position.name %></td>
  <td class="col-md-1"><%= position.quantity %></td>
  <td class="col-md-1"><%= position.ticker %></td>
  <td>
    <%= form_for [@portfolio, position, @movement] do |f| %>
    <div id = "movement-errors">
      <% if @movement.errors.any? %>
        <%= render 'shared/error_messages', object: @movement %>
      <% end %>
    </div>

    <div class="field">
      <%= f.label :quantity %>
      <%= f.number_field :quantity, class: 'form-control' %>
    </div>
    <div class="actions">
       <%= f.submit class: 'btn btn-primary' %>
     </div>
    <% end %>
  </td>
</tr>

我的部分共享错误是:

<% if object.errors.any? %>
  <div id = "error_explanation">
    <div class = "alert alert-danger">
      The form contains <%= pluralize(object.errors.count, "error") %>.
    </div>
    <ul>
      <% object.errors.full_messages.each do |msg| %>
        <li><%= msg %></li>
      <% end %>
    </ul>
  </div>
<% end %>

当我在移动表单上提交 nil 值时,我希望弹出错误并告诉用户消息。我有验证检查是否存在数量。

class Movement < ApplicationRecord
  belongs_to :position
  validates :quantity, presence: true

我的控制器动作#create action 看起来像

class MovementsController < ApplicationController
  before_action :load_portfolio_and_position 

def create
  @movement = Movement.new(movement_params)
  @movement.position_id = @position.id
  @movement.update_price
  @movement.date = DateTime.now
  @movement.trade ='buy'

  respond_to do |format|
    if @movement.save
      @position.update_attribute(:quantity, (@movement.quantity + @position.quantity))
      format.html { redirect_to @portfolio, notice: 'Movement was successfully created.' }
    format.js
    else
      format.html { render template: 'portfolios/show' }
      format.json { render json: @movement.errors, status: :unprocessable_entity }
      format.js
    end
  end
end

就目前而言,当我提交一个空表单时,我使用 better_errors gem 得到了这个错误:

'nil' 不是 ActiveModel 兼容的对象。它必须实现 :to_partial_path。

我的作品集展示页面中突出显示了渲染@positions 行。我以为我正在实施部分路径。我的语法错了吗?

【问题讨论】:

  • 也许我是个盲人,但我看不到您在控制器中设置@portfolio 的位置。
  • 我编辑显示我的运动控制器 before_action。我在所有动作之前抓取投资组合和位置对象。
  • 你在load_portfolio_and_position 方法中抓取@positions对象吗?
  • 听起来你没有分配@positions - 并且你的 before_action 的命名意味着你正在设置@portfolio@position - 而不是@positions。即使您正在分配它们,也要检查它们是否被分配为零。
  • 您可以在其中放置一个 nil 检查,如果变量为 null,则将其设置为正确类型的空模型实例。

标签: ruby-on-rails ruby


【解决方案1】:

传递对象时,需要这样赋值。

&lt;%= render partial: 'shared/error_messages', locals: {object: @movement} %&gt;

http://guides.rubyonrails.org/layouts_and_rendering.html#passing-local-variables

【讨论】:

    【解决方案2】:

    当您使用 object: 属性将对象传递给部分时,部分会通过部分名称引用该对象

    例如

    当你打电话时

    <%= render 'shared/error_messages', object: @movement %>
    

    shared/error_messages 部分将有一个局部变量 error_messages 引用 @movement

    当我只将一个对象传递给部分对象时,我喜欢使用 'as'

    例如

    <%= render 'shared/error_messages', object: @movement , as: :movement %>
    

    这使您可以指定局部变量的名称。如果我要传递多个对象,我会使用@7urkm3n 描述的方法。

    【讨论】:

      猜你喜欢
      • 2013-07-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-12-17
      • 2020-04-18
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多