Rails 包含集合的部分模板未正确呈现

Rails partial template with collection not rendering correctly

我已经解决这个错误几个小时了,但我不知道我做错了什么。我根本无法让项目集合为单个用户正确显示。每个项目属于一个用户,每个用户有很多项目。现在,我的部分未在用户显示视图上呈现。

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

我如何为每个用户显示正确的项目?我以前使用过几次局部,并且交叉引用了新旧代码。我看不出有什么区别,我正在失去理智。我搜索了一般互联网、Stack Overflow,并查看了 Rails Guides for Layouts and Rendering。我已经 post 编辑了下面的相关代码,并且很乐意 post 任何其他内容。请帮忙!

views/users/_item.html.erb

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

views/users/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>

controllers/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

controllers/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

尝试这样渲染:

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

并在 _partial 文件中循环:

<% user_items.each do |item| %>
...
<% end %>

您期望模板呈现比它更智能 - 它正在呈现所有项目,因为那是 @items 中的内容 - 它不知道您只需要给定用户的项目。原代码没有错

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

安装 byebug gem,通过在命令行上 运行ning 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。它是什么 return?

也试试 @user.inspect。它 return 是一个用户对象吗?

然后@user.items。 return 是什么意思?如果 @user.items return 是预期的项目集合,那么您将其传递给视图的方式或您在视图中对其进行的操作存在问题。

如果 @user.items 不是 return 项目集合,那么这就是它没有显示在您的视图中的原因!在这种情况下,它可能与您的 ActiveRecord 关联有关 and/or 您的迁移。

另一种可能性是您数据库中的当前项目可能是在您设置关联之前创建的,因此它们不会有 user_id。您可以在 rails 控制台中查看。确保您的数据库中的项目与您的 current_user.

具有相同的 user_id

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

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

在这里评论你的发现。