2016-06-22 1 views
0

Я использую Rails 4.2.6/PostgreSQL и пытаюсь сделать динамическое обновление в индексе, который имеет форму и генерируется эшафотом. Я думаю, что делаю все правильно, но проблема с рендерингом частично через rjs. Bellow - это ошибка и код. Есть идеи? Или RJS по-прежнему доступен в Rails 4 ??RJS Динамическое обновление ActionView :: Template :: Error (undefined method `each 'for nil: NilClass)

Сервер

Started POST "/users" for 127.0.0.1 at 2016-06-21 18:50:59 -0700 
Processing by UsersController#create as JS 
    Parameters: {"utf8"=>"✓", "user"=>{"name"=>"Tim"}, "commit"=>"Create User"} 
    (0.3ms) BEGIN 
    SQL (0.9ms) INSERT INTO "users" ("name", "created_at", "updated_at") VALUES ($1, $2, $3) RETURNING  "id" [["name", "Tim"], ["created_at", "2016-06-22 01:50:59.194072"], ["updated_at", "2016-06-22  01:50:59.194072"]] 
    (63.8ms) COMMIT 
    Rendered users/_user.html.erb (37.6ms) 
    Rendered users/create.js.erb (42.8ms) 
Completed 500 Internal Server Error in 145ms (ActiveRecord: 65.4ms) 

ActionView::Template::Error (undefined method `each' for nil:NilClass): 
    1:  <% @users.each do |user| %> 
    2:  <tr> 
    3:   <td><%= user.name %></td> 
    4:   <td><%= link_to 'Show', user %></td> 
    app/views/users/_user.html.erb:1:in  `_app_views_users__user_html_erb___2381841639716957386_70119033868960' 
    app/views/users/create.js.erb:1:in `_app_views_users_create_js_erb__1865303298608397742_00' 
    app/controllers/users_controller.rb:30:in `create' 

create.js.erb

$("#users").append("<%= escape_javascript(render @user) %>"); 

users_controller.rb

class UsersController < ApplicationController 
    before_action :set_user, only: [:show, :edit, :update, :destroy] 

    # GET /users 
    # GET /users.json 
    def index 
    @users = User.all 
    @user = User.new 
    end 

    # GET /users/1 
    # GET /users/1.json 
    def show 
    end 

    # GET /users/new 
    def new 
    @user = User.new 
    end 

    # GET /users/1/edit 
    def edit 
    end 

    # POST /users 
    # POST /users.json 
    def create 
    @user = User.new(user_params) 

    respond_to do |format| 
     if @user.save 
     format.html { redirect_to @user, notice: 'User was successfully created.' } 
     format.json { render :show, status: :created, location: @user } 
     format.js 
     else 
     format.html { render :new } 
     format.json { render json: @user.errors, status: :unprocessable_entity } 
     end 
    end 
    end 

    # PATCH/PUT /users/1 
    # PATCH/PUT /users/1.json 
    def update 
    respond_to do |format| 
     if @user.update(user_params) 
     format.html { redirect_to @user, notice: 'User was successfully updated.' } 
     format.json { render :show, status: :ok, location: @user } 
     else 
     format.html { render :edit } 
     format.json { render json: @user.errors, status: :unprocessable_entity } 
     end 
    end 
    end 

    # DELETE /users/1 
    # DELETE /users/1.json 
    def destroy 
    @user.destroy 
    respond_to do |format| 
     format.html { redirect_to users_url, notice: 'User was successfully destroyed.' } 
     format.json { head :no_content } 
    end 
    end 

    private 
    # Use callbacks to share common setup or constraints between actions. 
    def set_user 
     @user = User.find(params[:id]) 
    end 

    # Never trust parameters from the scary internet, only allow the white list through. 
    def user_params 
     params.require(:user).permit(:name) 
    end 
end 

приложение/просмотров/пользователей/index.html

<p id="notice"><%= notice %></p> 

<h1>Listing Users</h1> 

<table> 
    <thead> 
    <tr> 
     <th>Name</th> 
     <th colspan="3"></th> 
    </tr> 
    </thead> 

    <tbody id="users"> 
    <%= render @user %> 
    </tbody> 
</table> 

<br> 

<%= render 'form' %> 

приложение/просмотров/пользователей/_form.html.erb

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

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

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

Если я ставлю что-то вроде @users = User.all в создании действия, он будет отображает всех пользователей в два раза, как показано на рисунке ниже. enter image description here

+0

Страница '_user.html.erb 'ожидает объект @users с ожидаемым списком пользователей, но когда вы создаете @user, вы фактически не получаете значение для @users. –

+0

Как добавить @users = User.all в действие или что-то еще? – masaaki

+1

Вы пытались поставить @users = User.all сразу после 'if @ user.save' в' create'? Почему вы фактически возвращаете '@ user', если вы хотите перенаправить на страницу' index', а не 'show'? –

ответ

0

После попыток и ошибок, я подтвердил, что есть ответ в комментариях Раджеша. Это было немного непонятно в процессе попыток, но вот как я это понимаю.

create.js.erb

Перед

$("#users").append("<%= escape_javascript(render @user) %>"); 

После

$("#users").html("<%= escape_javascript(render @user) %>"); 

users_controller.rb

Перед Защиты создать @user = User.new (user_params)

respond_to do |format| 
    if @user.save 
     format.html { redirect_to @user, notice: 'User was successfully created.' } 
     format.json { render :show, status: :created, location: @user } 
     format.js 
    else 
    . 
    . 

После Защиты создать @user = User.new (user_params)

respond_to do |format| 
    if @user.save 
    @users = User.all 
     format.html { redirect_to @user, notice: 'User was successfully created.' } 
     format.json { render :show, status: :created, location: @user } 
     format.js 
    else 
    . 
    . 

Тогда все работает нормально. На самом деле они имеют смысл для обоих: для ошибки nil и добавления рендеринга. Спасибо, что ответил на вопрос Раджеша. В следующий раз попробуйте отправить его в разделе ответов.

 Смежные вопросы

  • Нет связанных вопросов^_^