Rails部分模板,集合无法正确呈现

时间:2016-06-01 21:07:31

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

我一直在排除这个错误几个小时,我不知道我做错了什么。我根本无法为单个用户正确显示项目集合。每个项目属于单个用户,每个用户都有许多项目。现在,我的部分不在用户显示视图上呈现。

如果我改变<%= render partial: "/users/item", collection: @user.items %>  到<%= render partial: "/users/item", collection: @items %>然后呈现部分模板,但无论他们属于哪个用户,都会显示所有项目。检查数据库后,每个项目条目都与外键user_id正确存储,因此这不是问题。

如何为每个用户显示正确的项目?我以前曾多次使用过部分内容,并且我交叉引用了旧代码和新代码。我看不出差异,我正在失去理智。我搜索了一般的互联网Stack Overflow,并查看了Rails Guides for Layouts and Rendering。我已在下面发布了相关代码,并乐意发布其他任何内容。请帮忙!

视图/用户/ _item.html.erb

<div>
  <h4>ITEM: <%= item.title %></h4>
  <p class="item"><%= item.cost %></p>
</div>

视图/用户/ show.html.erb

<h1>Users#show</h1>
<p>Find me in app/views/users/show.html.erb</p>

<div><%= @user.first_name %></div>

<h3>My List</h3>
<%= render partial: "/users/item", collection: @user.items %>

<span>ADD ITEM&nbsp;<%= link_to image_tag("Plus-50.png"), new_user_item_path(@user), class: "items-nved" %> </span>

控制器/ users_controller.rb

class UsersController < ApplicationController

  before_action :set_user, only: [:show, :edit, :update, :destroy]

  def index
    @users = User.all
    render :index
  end

  def show
    @user = User.find(params[:id])
    # @item = Item.find(params[:id])
    @items = Item.all
    @item = Item.new
    @item.user_id = @user.id
  end

  def new
    @user = User.new
  end

  def create
    @user = User.new(user_params)
    if @user.save
      redirect_to new_session_path, method: :get
    else
      render "new"
   end
  end

  def edit
  end

  def update
  end

  def destroy
  end

  private
  def set_user
   @user = User.find(params[:id])
  end

  def user_params
    params.require(:user).permit(:first_name, :last_name, :birthday, :city, :state, :email, :password, :password_confirmation)
  end
end

控制器/ items_controller.rb

class ItemsController < ApplicationController

  include ItemsHelper

  before_filter :require_login, only: [:new, :create, :update, :destroy]

  def index
    @current_user = current_user
    @items = Item.all
  end

  def show
    @user = current_user
    @item = Item.find(params[:id])
  end

  def new
    @user = current_user
    @item = Item.new
  end

  def create
    @user = current_user
    @item = Item.new(item_params)
    @item.user_id = params[:user_id] # set user_id param from database to current_user id
    @item.save

    redirect_to user_item_path(@user, @item)
  end

  def edit
    @user = current_user
    @item = Item.find(params[:id])
  end

  def update
   @user = current_user
   @item = Item.find(params[:id])
   @item.update(item_params)
   redirect_to user_path(@user)
  end

  def destroy
    @user = User.find params[:user_id]
    @item = Item.find(params[:id])
    @item.destroy
    redirect_to user_path(@user)
  end
end

private
  def user_params
    params.require(:user).permit(:first_name, :last_name, :birthday, :city, :state, :email, :password, :password_confirmation)
  end

  def require_login
    unless logged_in?
      flash[:error] = "You must be logged in to access this section"
      redirect_to new_login_url # halts request cycle
    end
  end

3 个答案:

答案 0 :(得分:1)

安装byebug gem,方法是在命令行上运行gem install byebug或将byebug放在Gemfile中(然后运行bundle install)。

byebug放在UsersController中@user声明之后,如下所示:

class UsersController < ApplicationController

  before_action :set_user, only: [:show, :edit, :update, :destroy]

  def index
    @users = User.all
    render :index
  end

  def show
    @user = User.find(params[:id])
    byebug

然后启动本地服务器并在浏览器中转到用户显示视图。该页面不会呈现,因为当它点击byebug时,服务器会暂停。

发生这种情况时,请返回终端并查看服务器日志。它将等待你的命令。输入@user,然后按Enter键。它又回归了什么?

另请尝试@user.inspect。它是否返回User对象?

然后做@user.items。那回报是什么?如果@user.items返回预期的项目集合,那么将视图传递给视图或者您在视图中使用它的方式有问题。

如果@user.items没有返回项目集合,那么这就是为什么它没有显示在您的视图中!在这种情况下,它可能与您的ActiveRecord关联和/或您的迁移有关。

另一种可能性是,在建立关联之前,可能已经创建了数据库中的当前项,因此它们没有user_id。您可以在rails控制台中进行检查。确保数据库中的项目与current_user具有相同的user_id。

在rails控制台中做的另一件好事是将一个您认为有一些项目的用户分配给变量,例如user = User.first,然后执行user.items。这有用吗?

我还建议编写一些RSpec测试,至少在模型级别测试是否存在正确的关联。 shoulda gem对此非常有用。

在此评论您的发现。

答案 1 :(得分:0)

尝试渲染它:

wchar_t

并将其循环到_partial文件中:

<%= render partial: "/users/item", locals: {user_items: @user.items} %>

答案 2 :(得分:0)

您希望模板呈现比实际更智能 - 它会渲染所有项目,因为它是@items中的内容 - 它没有&#39 ; t知道你只想要给定用户的物品。原始代码没有错误

render partial: "/users/item", collection: @user.item