【问题标题】:before_filter :authenticate_user!, except: [:index] / Rails 4before_filter :authenticate_user!,除了:[:index] / Rails 4
【发布时间】:2013-07-28 11:25:42
【问题描述】:

我有一个Listings Controller(设计用户系统),并且在 Rails 3 中我刚刚使用过

before_filter :authenticate_user!, except: [:index]

在查看特定列表之前检查用户是否已登录。

我的主页(索引)在底部显示一个视图列表,用户可以看到它们,但只要他点击一个查看它,他就会被重定向到登录页面。

这就是为什么在我的控制器中我有而不是

Listing.new -> current_user.listings.new

Rails 4 中,事情似乎发生了变化,我找不到正确的方法。

稍微搜索了一下,发现命令改成了

before_action :authenticate_user!, :except => [:index]

访客现在可以查看索引,但如果他点击列表,他不会被重定向到登录页面,而是出现此错误。

NoMethodError in ListingsController#show
undefined method `listings' for nil:NilClass

# Use callbacks to share common setup or constraints between actions.
def set_listing
        @listing = current_user.listings.find(params[:id])
end

# Never trust parameters from the scary internet, only allow the white list through.

我的列表控制器

class ListingsController < ApplicationController
  before_action :set_listing, only: [:show, :edit, :update, :destroy]
    before_action :authenticate_user!, :except => [:index]

  # GET /listings
  # GET /listings.json
  def index
    @listings = Listing.order("created_at desc")
  end

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

  # GET /listings/new
  def new
        @listing = current_user.listings.build
  end

  # GET /listings/1/edit
  def edit
  end

  # POST /listings
  # POST /listings.json
  def create
        @listing = current_user.listings.build(listing_params)

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

  # PATCH/PUT /listings/1
  # PATCH/PUT /listings/1.json
  def update
    respond_to do |format|
      if @listing.update(listing_params)
        format.html { redirect_to @listing, notice: 'Listing was successfully updated.' }
        format.json { head :no_content }
      else
        format.html { render action: 'edit' }
        format.json { render json: @listing.errors, status: :unprocessable_entity }
      end
    end
  end

  # DELETE /listings/1
  # DELETE /listings/1.json
  def destroy
    @listing.destroy
    respond_to do |format|
      format.html { redirect_to listings_url }
      format.json { head :no_content }
    end
  end

  private
    # Use callbacks to share common setup or constraints between actions.
    def set_listing
            @listing = current_user.listings.find(params[:id])
    end

    # Never trust parameters from the scary internet, only allow the white list through.
    def listing_params
      params.require(:listing).permit(:title, :description, :image)
    end
end

编辑:问题 2

如果另一个登录用户尝试查看另一个用户创建的列表,我会得到这个 ->

和日志

【问题讨论】:

  • 你可能想在set_listing之前做authenticate_user
  • 您的意思是将authenticate_user 移到set_listing 行上方?
  • 刚刚,我工作了.. 你介意发布一个答案以便我投票吗? :)
  • 哦,但是现在如果用户想查看其他用户的列表 -> ListingsController 中的 NoMethodError#show undefined method `listings' for nil:NilClass
  • before_actionbefore_filter stackoverflow.com/questions/16519828/… 的别名

标签: ruby-on-rails authentication devise ruby-on-rails-4


【解决方案1】:

set_listing 之前调用authenticate_user,这样current_user 就不是nil

before_action :authenticate_user!, :except => [:index]
before_action :set_listing, only: [:show, :edit, :update, :destroy]

【讨论】:

    【解决方案2】:

    试试这个,这将允许客人看到参数中提供的列表:

    def set_listing
        unless current_user
            @listing = Listing.find(params[:id])
        else
            @listing = current_user.listings.find(params[:id])
        end
    end
    

    更新:

    您似乎想按参数而不是current_user 显示列表。如果是这样,请更新您的set_listing 定义如下:

    def set_listing
        @listing = Listing.find(params[:id]) if params[:id]
    end
    

    【讨论】:

    • 在 Neo 的帮助下,我完成了之前的操作。但是现在,如果我在另一个帐户中登录并尝试查看不是由我创建的列表,我将得到“ListingsController 中的 NoMethodError #show undefined method `listings' for nil:NilClass”。也可以使用您的代码:(
    • @TheMiniJohn,你能从你的日志中发布跟踪吗?
    • 哦,那是因为该列表不属于当前用户。为什么不直接通过id 查找列表,因为您正在传递它。更合适的方法是,一旦用户通过身份验证,您的index 页面只显示登录用户的列表,这样您就不会遇到这样的错误。
    • 用户现在可以查看其他用户列表,但也可以编辑它们:(
    • @TheMiniJohn,在您的show.html.erb 上,您现在要检查列表是否属于当前用户,如果是,则显示编辑链接,否则不显示编辑链接。例如&lt;%= link_to_if(@listing.user == current_user, "edit", {controller: "listings", action: "edit"}) %&gt;
    【解决方案3】:

    before_filter :authenticate_user!, except: [:index]

    当我们想在用户未登录时将用户重定向到特定页面时使用。

    在此",except[:index]" 中,索引是Html 的页面名称,您希望将用户重定向到该视图。

    【讨论】:

      【解决方案4】:

      是的 你需要在set_listing之前调用authenticate_user,这样current_user就不是nil

      before_action :authenticate_user!, :except => [:index]
      before_action :set_listing, only: [:show, :edit, :update, :destroy]
      

      喜欢这个

      【讨论】:

      • 这个答案和我的有什么不同?
      猜你喜欢
      • 2013-05-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多