我正在研究我的RoR技能和学校作业我被要求在帖子政策中创建一个范围子类,以便允许具有特定角色(管理员,主持人,成员和访客)的用户能够查看具有不同访问量的帖子。以管理员或主持人身份登录时,所有帖子都应该可见。作为成员,只有登录成员发布的帖子应该是可见的。作为嘉宾,不应该看到任何帖子。
当我以管理员或主持人身份登录时,我可以查看网站上的所有帖子,但是,当以会员或访客身份查看网站时,我无法正常工作并收到错误。有人可以帮忙吗?
我收到错误:
ActiveRecord::StatementInvalid in Posts#index
Showing /Users/Jason/code/bloccit/app/views/posts/index.html.erb where line #7 raised:
SQLite3::SQLException: no such column: posts.published: SELECT "posts".* FROM "posts" WHERE "posts"."published" = 't' ORDER BY created_at DESC
<%= link_to "New Post", new_post_path, class: 'btn btn-success' %>
<% end %>
<% @posts.each do |post| %>
<div class="media">
<div class="media-body">
<h4 class="media-heading">
这是我的观点/帖子/ index.html.erb
<h1>All Posts</h1>
<% if policy(Post.new).create? %>
<%= link_to "New Post", new_post_path, class: 'btn btn-success' %>
<% end %>
<% @posts.each do |post| %>
<div class="media">
<div class="media-body">
<h4 class="media-heading">
<%= link_to post.title, post %>
</h4>
<small>
submitted <%= time_ago_in_words(post.created_at) %> ago by <%= post.user.name %><br>
<%= post.comments.count %> Comments
</small>
</div>
</div>
<% end %>
post_policy.rb
class PostPolicy < ApplicationPolicy
def index?
true
end
class Scope < Scope
attr_reader :user, :scope
def initialize(user, scope)
@user = user
@scope = scope
end
def resolve
if user.admin? || user.moderator?
scope.all
else
scope.where(:published => true)
end
end
end
end
application_policy.rb
class ApplicationPolicy
attr_reader :user, :record
def initialize(user, record)
@user = user
@record = record
end
def index?
false
end
def show?
scope.where(id: record.id).exists?
end
def create?
user.present?
end
def new?
create?
end
def update?
user.present? && (record.user == user || user.admin?)
end
def edit?
update?
end
def destroy?
update?
end
def scope
record.class
end
class Scope
attr_reader :user, :scope
def initialize(user, scope)
@user = user
@scope = scope
end
def resolve
scope
end
end
end
post.rb
class Post < ActiveRecord::Base
has_many :comments
belongs_to :user
default_scope { order('created_at DESC') }
end
user.rb
class User < ActiveRecord::Base
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable, :confirmable
has_many :posts
def admin?
role == 'admin'
end
def moderator?
role == 'moderator'
end
def member?
role == 'member'
end
end
最后,这是我的posts_controller.rb
class PostsController < ApplicationController
def index
@posts = policy_scope(Post)
end
def show
@post = Post.find(params[:id])
end
def new
@post = Post.new
authorize @post
end
def create
@post = Post.new(params.require(:post).permit(:title, :body))
@post.user = current_user
authorize @post
if @post.save
flash[:notice] = "Post was saved."
redirect_to @post
else
flash[:error] = "There was an error saving the post. Please try again."
render :new
end
end
def edit
@post = Post.find(params[:id])
authorize @post
end
def update
@post = Post.find(params[:id])
authorize @post
if @post.update_attributes(params.require(:post).permit(:title, :body))
flash[:notice] = "Post was updated."
redirect_to @post
else
flash[:error] = "There was an error saving the post. Please try again."
render :edit
end
end
end
答案 0 :(得分:1)
您的PostPolicy
def resolve
if user.admin? || user.moderator?
scope.all
else
scope.where(:published => true)
end
end
正如您所说,当您以 成员 登录时收到错误,因此在上述方法中,else
块将被执行并且它查找posts
:published
true
published
。因此,当 没有 posts
表中的published
列时,会触发错误。
要解决此问题,请创建一个迁移文件,将boolean
添加为true
属性,并将默认值设置为posts
到class AddPublishedToPosts < ActiveRecord::Migration
def change
add_column :posts, :published, :boolean, :default => true
end
end
表。
您的迁移文件将如下所示
rake:db:migrate
做private void BindGridTL()
{
clsTeamLeadDashboard clsTeamLead = new clsTeamLeadDashboard();
DataSet ds = new DataSet();
clsTeamLead.Month = DateTime.Now.Month.ToString();
clsTeamLead.Year = DateTime.Now.Year.ToString();
ds = clsTeamLead.BindTLDashBoardDatewise();
Label lblName = (Label)GridView1.FindControl("lblName");
lblName.Text = ds.Tables[0].Rows[0]["Name"].ToString();
hdName.Value = ds.Tables[0].Rows[0]["Name"].ToString();
GridView1.DataSource = ds;
GridView1.DataBind();
}
答案 1 :(得分:0)
SQLite3::SQLException: no such column: posts.published:
错误表示您的表格中没有published
属性,根据您的查询,该属性当然是boolean
类型
SELECT "posts".* FROM "posts" WHERE "posts"."published" = 't' ORDER BY created_at DESC
请向您的帖子模型添加迁移:
$ rails g migration add_published_to_posts published:boolean
然后将默认值添加到published
属性
class AddPublishedToPosts < ActiveRecord::Migration
def change
add_column :posts, :published, :boolean, :default => false
end
end
最后,运行:$ rake db:migrate