【问题标题】:ActiveRecord::StatementInvalid, SQLite3::SQLException: no such column:ActiveRecord::StatementInvalid,SQLite3::SQLException:没有这样的列:
【发布时间】:2015-07-27 04:37:35
【问题描述】:

我正在研究我的 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

用户.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

【问题讨论】:

  • posts 表中有published 列吗?这行scope.where(:published =&gt; true) 给你造成了问题。
  • @Pavan 谢谢! published 没有添加到 posts 表中,我回去添加它然后运行 ​​rake db:migrate。现在没有错误被提出。但是,当我以会员身份登录时,我仍然无法查看任何帖子,即使在我以会员身份创建它们之后也是如此。
  • 一些帖子的:published 设置为true 并检查。

标签: ruby-on-rails ruby activerecord sqlite


【解决方案1】:

你的PostPolicy中有这个方法

def resolve
  if user.admin? || user.moderator?
     scope.all
   else
     scope.where(:published => true)
   end
end

正如你所说,当你以 member 身份登录时会出错,因此在上述方法中,else 块将被执行并寻找posts 其中:publishedtrue。因此,当您没有posts 表中的published 列时,会触发错误。

要解决此问题,请创建一个迁移文件以将published 添加为boolean 属性,并将默认值设置为trueposts 表。

您的迁移文件将如下所示

class AddPublishedToPosts < ActiveRecord::Migration
  def change
    add_column :posts, :published, :boolean, :default => true
  end
end

然后rake:db:migrate

【讨论】:

  • 非常感谢!这就是它所做的。现在工作正常。
【解决方案2】:
SQLite3::SQLException: no such column: posts.published:

错误提示您的表中没有 published 属性,根据您的查询,这当然是 boolean 类型

SELECT "posts".* FROM "posts"  WHERE "posts"."published" = 't'  ORDER BY created_at DESC

请向您的 Post 模型添加迁移:

$ 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

【讨论】:

    猜你喜欢
    • 2013-10-09
    • 2011-08-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-08-24
    • 2015-10-08
    • 2016-12-08
    • 1970-01-01
    相关资源
    最近更新 更多