Rails: почему нулевой объект на мой взгляд

#ruby-on-rails #ruby-on-rails-3 #ruby-on-rails-3.1

#ruby-on-rails #ruby-on-rails-3 #ruby-on-rails-3.1

Вопрос:

Я создал очень простое приложение Rails 3.1 с базовыми элементами, такими как:

Мой PostsController.rb имеет new , index , create методы:

 def index
    @posts = Post.all

    render :index
end
def new
   @post = Post.new
   render :new
end

def create
    @post = Post.new(params[:post])

    if @post.save
      render :index

    else
      render :new

    end

  end
  

Новая форма .html.erb:

 <%= form_for @post do |f| %>
  <%= f.error_messages%>
  <p>
    <%= f.label :name %><br />
    <%= f.text_field :name %>
  </p>
  <p>
    <%= f.label :address %><br />
    <%= f.text_field :address, :size=>60 %>
  </p>

  <p>
    <%= f.submit 'Create' %>
  </p>
<% end %>
  

представление индекса (index.html.erb):

 <table>
<% @posts.each do |post| %>
  <tr>
    ...
  </tr>
<% end %>
</table>
  

мой routes.rb определил:

 resources :posts
root :to => 'post#new'
  

Учитывая все вышесказанное, при отправке новой формы будет create вызван метод в PostController, затем внутри create метода, если новая запись будет успешно сохранена, это произойдет render :index , то есть для отображения представления index.html.erb, на данный момент все в порядке. но теперь я получил ошибку в представлении index.html.erb:

Он жалуется, что @posts в <% @posts.each do |post| %> равен нулю, почему???

————-Я тоже пробовал————————-

Я попытался использовать redirect_to posts_path create метод in, затем я получил ошибку неопределенного метода `posts_path_url’

Я также пытался использовать redirect_to :index create метод in, затем я получил ошибку неопределенного метода `index_url’

Ответ №1:

Ошибка возникает из @posts -за того, что переменная не установлена в вашем Post#create методе, как в Post#index . Вы должны помнить, что рендеринг представления не вызывает соответствующий метод контроллера.

Вы хотите использовать redirect_to вместо render :

 def create
    @post = Post.new(params[:post])

    if @post.save
        redirect_to :posts
    else
        render :new
    end
end
  

Комментарии:

1. Привет, спасибо, но, пожалуйста, проверьте мой пост, я также пытался использовать redirect_to:index, но появилось новое сообщение об ошибке, в котором жалуется «неопределенный метод `index_url'», как избавиться от этого тогда?

2. @Leem.fin извините, моя ошибка, это должно быть redirect_to posts_path

3. Спасибо, но я все еще получаю сообщение об ошибке «неопределенный метод `posts_path_url'»

4. @Leem.fin Я только что заметил, что у вас есть resources :post в вашем routes.rb. Попробуйте изменить это на resources :posts .

5. @Leem.fin Вы, вероятно, также захотите перейти root :to => 'post#new' на root :to => 'posts#new'

Ответ №2:

Это происходит потому, что вызов render не вызывает метод index на контроллере, он только разрешает путь к представлению и отображает его.

Если вы хотите, чтобы @posts присутствовал, вы должны установить его самостоятельно в своем действии create.

Это хорошо работает с методами new и create по умолчанию (сгенерированный каркас), потому что в обоих действиях вы настраиваете одну и ту же переменную экземпляра @post. Только в действии create, если проверка завершилась неудачно, вы можете мгновенно повторно использовать переменную экземпляра @post, в которой хранятся разные ошибки, и отобразить новый шаблон представления, чтобы отобразить форму post с ошибками.

Если вы хотите перенаправить на действие posts, вы должны использовать:

 redirect_to posts_path
  

Комментарии:

1. Но разве @posts = Post.all не должен быть внутри индексного метода? (вы сказали в методе create), если я хочу установить его в методе index, что следует изменить?

2. Я думаю, что неправильно понял ваш вопрос, я думал, вы хотите иметь несохраненный объект с ошибками в вашем действии создания. Вы должны использовать redirect_to, как предложил Маро.