validates_presence_of не работает должным образом ... как отладить? - PullRequest
1 голос
/ 28 апреля 2009

В моей модели Review у меня есть следующее:

class Review < ActiveRecord::Base
  belongs_to :vendor
  belongs_to :user
  has_many :votes  

  validates_presence_of :summary
end

Я отправляю новую запись в URL:

vendors/9/reviews/new

new.html.erb содержит следующую форму:

<%= error_messages_for 'review' %>

<h1>New review for <%= link_to @vendor.name, @vendor%></h1>

<% form_for(@review, :url =>vendor_reviews_path(@vendor.id)) do |f| %>
  <%= f.error_messages %>

  <p>
    <%= f.label :summary %><br />
    <%= f.text_area :summary, :rows=>'3', :class=>'input_summary' %>

    <%= f.hidden_field :vendor_id, :value => @vendor.id %>
  </p>
  <p>
    <%= f.submit 'Submit Review' %>
  </p>
<% end %>

Когда я оставляю поле для: резюме пустым, я получаю сообщение об ошибке, а не сообщение проверки:

У вас есть нулевой объект, когда вы этого не ожидали! Произошла ошибка при оценке nil.name

Извлеченный источник (вокруг строки № 3):

1: <%= error_messages_for 'review' %>
2: 
3: <h1>New review for <%= link_to @vendor.name, @vendor%></h1>

Я не понимаю, что происходит, это работает, если: заполнено резюме

  def new
    @review = Review.new
    @vendor = Vendor.find(params[:vendor_id])
    @review = @vendor.reviews.build

    respond_to do |format|
      format.html # new.html.erb
      format.xml  { render :xml => @review }
    end
  end

def create
    @review = Review.new(params[:review])

    #@vendor = Vendor.find(params[:vendor_id]) #instantiate the vendor from the URL id -- NOT WOKRING
    #@review = @vendor.reviews.build #build a review with vendor_id -- NOT working
    @review = @current_user.reviews.build params[:review]#build a review with the current_user id

    respond_to do |format|
      if @review.save
        flash[:notice] = 'Review was successfully created.'
        format.html { redirect_to review_path(@review) }
        format.xml  { render :xml => @review, :status => :created, :location => @review }
      else
        format.html { redirect_to new_review_path(@review) }
        format.xml  { render :xml => @review.errors, :status => :unprocessable_entity }
      end
    end
  end

Моя догадка заключается в том, что когда он терпит неудачу, он собирается redirect_to new_review_path(@review) и поэтому не знает поставщика. Как я могу вместо этого перенаправить на vendor/:vendor_id/reviews/new

Ответы [ 3 ]

0 голосов
/ 30 апреля 2009

Возможно, у вас не установлена ​​переменная-член @vendor, но для исправления было бы правильнее использовать не @vendor напрямую, а через экземпляр переменной @review.

Если вы создаете новую рецензию, у вас уже есть созданная переменная-член @review, и вы просто заполняете ее поля - поэтому вам нужно установить поставщика для @review (если это не обязательно) ... это будет вместо этого правильнее использовать @ review.vendor.name.

(Если вендор необязателен, то вы, очевидно, должны отследить все случаи vendor.nil?).

0 голосов
/ 03 мая 2009

Я думаю, вам нужно render :action => 'new' вместо вашего redirect_to new_review_path(@review). Это сохранит ваши сообщения об ошибках в объекте @review. При перенаправлении вы теряете старый объект и создаете новый.

Как уже говорили другие, перед рендерингом представления вам также необходимо убедиться, что вы заново заполнили переменную @vender в своем методе create.

PS. Мне нравится использовать плагин ardes resources_controller для таких стандартных действий контроллера, как эти, облегчает жизнь для меня и действительно хорошо обрабатывает вложенные ресурсы.

0 голосов
/ 28 апреля 2009

Какой код у вас есть в действиях new и create в ваших ReviewsController?

Я подозреваю, что ваш новый Review не проходит проверку, потому что поле summary пустое, а затем, когда форма повторно отображается при ошибке проверки, переменная экземпляра @vendor равна nil.

Необходимо убедиться, что @vendor присвоено значение для обоих путей кода.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...