ActiveRecord :: StatementInvalid,SQLite3 :: SQLException:没有这样的列:

时间:2015-07-27 04:37:35

标签: ruby-on-rails ruby activerecord sqlite

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

2 个答案:

答案 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属性,并将默认值设置为postsclass 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