产品中的NoMethodError #index undefined方法`each'for

时间:2014-09-06 04:25:51

标签: ruby-on-rails ruby rest ruby-on-rails-4 routes

我无法理解错误。

没有产品#index 12“sign_in @user”,当我登录这个网站并点击标题的“Kagushop”时,它会让我移动到root_path。我想转到从user_id获得的Products_index并查看所有产品的索引。

但是,使用Products#index 12“sign_in @user”,我在产品中找到了 NoMethodError #index undefined方法`每个'错误。

如果@poducts = Product.all,这将显示所有产品,但我无法保留我的user_id。我希望让我的user_id登录当前用户并查看所有产品。我应该怎么做?请帮帮我......



产品#指数(控制器)

class ProductsController < ApplicationController
  include ProductsHelper

  before_action :signed_in_user,only:[:new,:create]
  before_action :find_user_object

  def index
    #before actionで@userあり
    products_object_create_for_index
    unless signed_in?
      flash.now[:notice] = "You have to signin!!"
    else  
      sign_in @user
      @products = @user.products.build
      #@product = Product.find(params[:id])
      #redirect_to user_products_url(user_id:@user.id)
      render :template => "products/index", :collection => @products
    end
  end

  def show
    @products = @user.products.build
    @product = Product.find(params[:product_id])
  end


  def new
    # => 多分before action化させる方が良い
    #urlでproducts/newなっててUserのidが取れてない。
    redirect_to signin_url, notice:"U have to sign in to publish your furniture." unless sign_in @user
    @product = Product.new
  end

  def create
    @product = @user.products.build(products_params)
    if @product.save
      @product.update_attributes(:user_id => @user.user_id)
      flash[:success] = "You could add new item:)"
      redirect_to @user #後にaction: :indexに変更したい
    else
      flash.now[:error] = "You couldn't add an item."
      render 'new'
    end
  end

  def edit
  end

  def update
    if @product.update_attributes(products_params)
      flash[:success] =  "You updated your product info"
      redirect_to @products
    else
      flash.now[:error] = "couldn't update :("
      redirect_to products_edit_path
    end
  end

  def destroy
    #あった方がいいかもしれない@user = Product.find(params[:id])
    @product.destroy
    redirect_to root_url
  end




  private

  def products_params
    params.require(:product).permit(:id,:user_id,:name,:kind,:size,:discription,:price)
  end


  #before_action
  def signed_in_user
    redirect_to signin_url, notice:"Please sign in." unless signed_in? 
  end

  def find_user_object
    @user = User.find_by(params[:user_id])
  end

end

产品#指数(视图)

<div class="contents">
    <% unless @products.nil? && @all_products.nil? %>   
        <%unless signed_in? %>
            <%= render  'shared /valid_products_index' ,:collection => @products,:as => :products %> 
        <%else%>
            <%= render 'shared/not_signin_index',:collection => @all_products %>
        <%end%>
    <% else %>
        <p><strong>Anyone doesn't have added any items.</strong></p>
    <% end %>
</div>

应用程序/视图/产品/共享/ valid_products_index

<h1>Products#index </h1>
<p>Find me in app/views/products/index.html.erb</p>

<!--ここの@product-->


<% @products.each do |item| %>
    <ul>
        <!--画像を追加したい-->
        <li>Item name:<%= item.name %></li>
        <li>Kind of item:<%= link_to item.kind,user_product_path(user_id:@user.id,id:@user.id) %></li>
        <li>Size of item:<%= link_to item.size,user_product_path(id:@product.id,:user_id=>@user.user_id) %></li>
        <li>WHere's this from?:<%= link_to item.from,user_product_path(:id=>@product.id,:user_id=>@user.id) %></li>
        <li>Explanation:<%= link_to item.discription,user_product_path(:id=>@product.id,:user_id=>@user.id) %></li>
        <li>Price:<%= item.link_to item.price,user_product_path(:id=>@product.id,:user_id=>@user.id) %></li>
    </ul>
<% end %>

应用程序/视图/产品/共享/ not_signin_index

<h1>Products#index</h1>
<p>Find me in app/views/products/index.html.erb</p>

<ul>
<% @all_products.each do |item| %>
    <!--画像を追加したい-->
    <li>Item name:<%= link_to item.name, signout_path, method: :delete,confirm:"U have to sign in"  %></li>
    <li>Kind of item:<%= link_to item.kind, signout_path, method: :delete,confirm:"U have to sign in" %></li>
    <li>Size of item:<%= link_to item.name, signout_path, method: :delete,confirm:"U have to sign in" %></li>
    <li>WHere's this from?:<%= link_to item.name, signout_path, method: :delete,confirm:"U have to sign in" %></li>
    <li>Explanation:<%= link_to item.name, signout_path, method: :delete,confirm:"U have to sign in" %></li>
    <li>Price:<%= root_path(item.price) %></li>
<% end %>
</ul>

视图/布局/报头

<header>
<nav class="navbar nav-default " role="navigation">
    <div class="navbar-inner">

        <!--top-->
        <% unless signed_in? %> 
            <ul class="nav navbar-nav">
                <!--header left-->  
                <li class="navbar-text navbar-left">
                    <%= link_to "KaguShop", user_products_path(user_id:@user.user_id),id:"logo" %>
                </li>
            </ul>
        <% else %>
            <ul class="nav navbar-nav">
                <!--header left-->  
                <li class="navbar-text navbar-left">
                    <%= link_to "KaguShop", root_path,id:"logo" %>
                </li>
            </ul>   
        <% end %>


            <ul class="nav navbar-nav">
        <% unless signed_in? %>
            <li class="navbar-text">
                <%= link_to "contact", contact_path%>
            </li>
            <li class="navbar-text" id="right-nav2">    
                <button type="button" class="btn btn-default navbar-btn">               <a><%= link_to "Submit product!", new_user_product_path(user_id:@user.user_id) %></a>
                </button>
                <button type="button" class="btn btn-danger navbar-btn">
                    <a><%= link_to "Sign out!", signout_path,:confirm=>"Are u sure??" ,method:"delete" %></a>
                </button>               
            </li>
        <% else %>
            <li class="navbar-text navbar-right">
                <button type="button" class="btn btn-danger navbar-btn">
                    <a><%= link_to "Sign up!", signup_path %></a>
                </button>
                <button type="button" class="btn btn-info navbar-btn">
                    <a><%= link_to "Sign in!",signin_path %></a>
                </button>   
            </li>
        <% end %>
            </ul>

        <!--top-->
    </div>  
</nav>
</header>

的routes.rb

KaguShop::Application.routes.draw do
  resources :users,only:[:show,:new,:create,:edit,:update,:destroy] do
    resources :products,only:[:index,:new,:create,:destroy,:show,:new,:edit,:update]
  end

  resources :sessions,only:[:new,:create,:destroy]
  resources :carts,only:[:new,:create,:destroy]#,:showに関しては恐らくいらない。newで既にオブジェクトも作る

  match '/products/:id(/.:format)',to:'products#show',via:'get'

  root 'products#index'
  match '/signup', to:'users#new',via:'get'
  match '/signin', to:'sessions#new', via:'get'
  match '/signout', to:'sessions#destroy', via:'delete'
  match '/contact', to:'nomal_pages#contact', via:'get'

end

以下是我的SessionsHelper(包括sign_in方法。)

module SessionsHelper

    def sign_in(user)
        remember_token = User.new_remember_token
        cookies.permanent[:remember_token] = remember_token
        user.update_attribute(:remember_token,User.encrypt(remember_token))
        self.current_user=(user)        
    end

    def current_user=(user)
        @current_user = user
    end

    def current_user
        remember_token = User.encrypt(cookies[:remember_token])
        @current_user ||= User.find_by(remember_token:remember_token) 
    end

    def current_user?(user)
        user == current_user
    end

    def signed_in?
        current_user.nil?
    end

    def sign_out
        self.current_user = nil
        cookies.delete(:remember_token)
    end

    def redirect_back_or(default)
        redirect_to(session[:return_to]||default)
        session.delete(:return_to)
    end

    def store_location
        session[:return_to] = request.url
    end

    def signed_in_user
        unless signed_in?
            store_location
            redirect_to signin_url,notice:"Please sign in."
        end
    end

end

1 个答案:

答案 0 :(得分:1)

<强>对象

问题看起来与身份验证无关 - 您的products#index方法无法设置正确的对象,这似乎是一个问题。

您提到错误的内容类似于undefined method .each for nil:NilClass

修复应该是:

#app/controllers/products_controller.rb
class ProductsController < ApplicationController
   def index
      @products = user_signed_in? @user.products : Product.all
   end
end

这样您就可以在products#index视图中显示产品了:

#app/views/products/index.html.erb
<% if @products.present? %>
   <% @products.each do |product| %>
      <%= @product.name %>
   <% end %>
<% end %>

应该解决您的直接问题。是否修复了签到问题是另一回事。


<强>验证

高度建议使用Devise gem进行身份验证,特别是如果您是新用户。

除非您尝试从头开始学习编写身份验证的过程,否则Devise gem基本上完全您正在尝试创建的内容(即使使用相同的方法)。

你可以see more about Devise here

enter image description here