阻止用户浏览隐藏的作者

时间:2014-01-20 03:45:45

标签: ruby-on-rails ruby hide url-routing

我有一个索引页面,它使用布尔值隐藏/显示不同的作者。我遇到的问题是签名的用户仍然可以通过URL访问隐藏的作者和他们的书籍。

如何阻止当前用户通过网址导航到隐藏的作者及其相应的图书?如果隐藏作者,有没有办法将它们重定向回作者页面?

目前,我使用过Controllers&一个布尔值,用于帮助隐藏/显示已登录用户的作者或书籍。有人可以指出我正确的方向。这是我的代码。

模型

class Author < ActiveRecord::Base
  attr_accessible :name, :photo

  has_many :books

end

class Book < ActiveRecord::Base
  attr_accessible :author_id, :title, :photo

  belongs_to :author

end

控制器

class AuthorsController < ApplicationController
  before_filter :signed_in_user, only: [:index]
  before_filter :admin_user, only: [:edit, :update, :destroy, :new, :show]

  respond_to :html, :js

  ###Only displays unhidden authors to non admin users.  

  def index
    if current_user.admin?
      @authors = Author.all(:order => "created_at")
    else
      @authors = Author.where(:display => true).all(:order => "created_at")
    end
  end

  private

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

    def admin_user
      redirect_to(root_path) unless current_user.admin?
    end
end

class BooksController < ApplicationController
  before_filter :signed_in_user, only: [:index]
  before_filter :admin_user, only: [:edit, :update, :destroy, :new, :show]
  before_filter :get_author

  respond_to :html, :js

  def get_author
    @author = Author.find(params[:author_id])
  end

  def index
    @books = @author.books
  end

  private

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

    def admin_user
      redirect_to(root_path) unless current_user.admin?
    end
end

视图

Authors index.html.erb

<% @authors.each do |author| %>

  <%= link_to (image_tag author.photo(:medium)), 
    url_for(author_books_path(author)),
    class: "img-rounded" %>

<% end %>

### How Can I prevent Users from accessing Hidden Author's Books (Index Page)
Books index.html.erb

  <% @books.each do |book| %>
    <%= image_tag book.photo(:medium) %>
    <%= book.name %>
  <% end %>

路线

resources :authors do
  resources :books
end

SCHEMA

create_table "authors", :force => true do |t|
  t.string   "name"
  t.boolean  "display",             :default => false
  t.datetime "created_at",                             :null => false
  t.datetime "updated_at",                             :null => false
  t.string   "photo_file_name"
  t.string   "photo_content_type"
  t.integer  "photo_file_size"
  t.datetime "photo_updated_at"
end

create_table "books", :force => true do |t|
  t.integer  "author_id"
  t.string   "title"
  t.datetime "created_at",          :null => false
  t.datetime "updated_at",          :null => false
  t.string   "photo_file_name"
  t.string   "photo_content_type"
  t.integer  "photo_file_size"
  t.datetime "photo_updated_at"
end

3 个答案:

答案 0 :(得分:2)

使用适当的授权模型,例如CanCan

关键部分(适用于CanCan)将根据用户角色进行授权:

if user.role == admin
  can :manage, :all
else 
  can :read, Author, display: true
end

有一个有用的RailsCast可以引导您使用CanCan进行授权。

存在其他选项,例如Declarative Authorization,或者您可以自行推送。

答案 1 :(得分:2)

Use a proper authorization model, such as CanCan.

就个人而言,我不确定我是否同意这一点,至少考虑到你似乎试图解决的问题的范围。但是,您在/app/views/books/index.html.erb中的评论似乎表明您想在视图文件中放置一些逻辑。 NOT 执行此操作。遵循适当的MVC架构,您尝试做的事情属于业务逻辑类别。因此,控制它的代码应该在您的控制器中。

在您的/app/controllers/book_controller.rb文件中,根据作者的属性,更改作者图书页面的操作以重定向回作者。这样的事情:(不确定确切的路径是什么):

def index  
  # Redirect if author is set to hidden
  if !@author.display
    redirect_to author_path
  else  
    @books = @author.books  
  end  
end  

答案 2 :(得分:1)

在作者#show Controller中,您可以编写例如 -

Authors#Show
def show
 @author = Author.find(params[:id])
 redirect_to root_url unless @author.display
end

在这种情况下,当用户访问任何作者的网址时,它会检查该作者的显​​示属性是否为真,并相应地重定向。