Rails 4 - 验证模型不起作用

时间:2016-11-25 09:20:02

标签: ruby-on-rails ruby-on-rails-4

感谢你帮助我。我有一个rails项目,人们可以预订飞机票(不是真正的项目,只是想学习铁路:) :)。

我有两个cfaffolded对象 - '席位'和'航班'和客户可以从每个航班页面购买座位(座位加载为部分)。

我的/app/views/flights/show.html.erb看起来像这样:

<p>
  <strong>Departure:</strong>
  <%= @flight.departure %>
</p>

<p>
  <strong>Destination:</strong>
  <%= @flight.destination %>
</p>

<p>
  <strong>Baggage allowance:</strong>
  <%= @flight.baggage_allowance %>
</p>

<%= render partial: "new_seat", locals: {seat: Seat.new(flight_id: @flight.id)} %>
<%= link_to 'Edit', edit_flight_path(@flight) %> |
<%= link_to 'Back', flights_path %>

我的new_seat部分/app/views/flights/_new_seat.html.erb:

<h1>New Seat</h1>

<%= form_for(seat) do |f| %>
  <% if seat.errors.any? %>
    <div id="error_explanation">
      <h2><%= pluralize(seat.errors.count, "error") %> prohibited this seat from being saved:</h2>

      <ul>
      <% seat.errors.full_messages.each do |message| %>
        <li><%= message %></li>
      <% end %>
      </ul>
    </div>
  <% end %>

  <%= f.hidden_field :flight_id %>
  <div class="field">
    <%= f.label :name %><br>
    <%= f.text_field :name %>
  </div>
  <div class="field">
    <%= f.label :baggage %><br>
    <%= f.text_field :baggage %>
  </div>
  <div class="actions">
    <%= f.submit %>
  </div>
<% end %>

如果它很重要 - 我通过从/app/views/seats/new.html.erb

复制它来自己创建new_seat

现在我需要验证行李数量以防止我的客户抓住大包。我这样写了我的/app/models/seat.rb:

class Seat < ActiveRecord::Base
    belongs_to :flight
    def validate
        if baggage > flight.baggage_allowance
          seat.errors.add(:base, message: "You have too much baggage")
        end
    end
end

但它不起作用 - 当客户在行李领域进入大额时,网站上没有错误。我做错了什么?

2 个答案:

答案 0 :(得分:2)

validate方法已经可用(它是ActiveRecord为我们提供实现自定义验证的类方法)。您可以使用AR提供的方法。类似下面的代码

validate :check_baggage_limit

def check_baggage_limit
  if baggage > self.flight.baggage_allowance
    self.errors.add(:base, "You have too much baggage")
  end
end

答案 1 :(得分:1)

您可以通过两种方式添加自定义验证。 首先是自定义方法,如下所示

class Seat < ActiveRecord::Base
  belongs_to :flight

  validate :baggage_limit
  def baggage_limit
    if baggage > flight.baggage_allowance
      errors.add(:base, message: "You have too much baggage")
    end
  end
end

其次是自定义验证器

class BaggageValidator < ActiveModel::Validator
  def validate(seat)
    if seat.baggage > seat.flight.baggage_allowance
      seat.errors.add(:base, message: "You have too much baggage")
    end
  end
end

class Seat < ActiveRecord::Base
  include ActiveModel::Validations
  belongs_to :flight
  validates_with BaggageValidator
end

您必须误读http://guides.rubyonrails.org/active_record_validations.html#custom-validators