第一貼這裏,所以我希望它是有道理的,但我一直在旋轉我的車輪太久了。 首先是一個小背景。我正在構建一個包含3個模型的Wiki應用程序:用戶,Wiki和協作(連接表)。評論家的政策範圍有很多通過關係
我正在使用Devise和Pundit,並有4類用戶應根據他們的狀態查看維基的不同子集。
這裏的規則:
- 公衆用戶(未登錄) - 應查看(無需編輯)僅公共維基 (:隱藏=>假)
- 身份驗證的用戶(:角色=>「標準「) - 應 查看,編輯&僅刪除公共維基。
- 高級用戶(:角色=> 「溢價」) - 查看,編輯,刪除公共wiki和創造 私人維基的能力(:隱藏=>真),並添加合作者的私人 維基這給他們編輯維基的權利。
- Admin(:role =>「admin」)完全控制所有記錄。
所以我在政策範圍內(用戶檢查狀態)一個漫長scope.joins條件我維基索引視圖給予CURRENT_USER的基於角色維基列表的一個子集。
信念使噴出了這樣的錯誤:
Started POST "/__better_errors/59802a57d82fd17e/variables" for 127.0.0.1 at 2014-12-02 09:05:41 -0800
Wiki Load (0.4ms) SELECT "wikis".* FROM "wikis" INNER JOIN "collaborations" ON "collaborations"."wiki_id" = "wikis"."id" WHERE (hide = 'f' or user_id = 2 or collaborations.user_id = 2)
SQLite3::SQLException: ambiguous column name: user_id: SELECT "wikis".* FROM "wikis" INNER JOIN "collaborations" ON "collaborations"."wiki_id" = "wikis"."id" WHERE (hide = 'f' or user_id = 2 or collaborations.user_id = 2)
這裏的政策
class WikiPolicy < ApplicationPolicy
# What collections a user can see users `.where`
class Scope < Scope
def resolve
if user && user.role == 'admin'
scope.all
elsif user
scope.joins(:collaborations).where("hide = :hide or user_id = :owner_id or collaborations.user_id = :collaborator_id", {hide: false, owner_id: user.id, collaborator_id: user.id})
else
scope.where hide: false
end
end
end
#Policies are boolean logic true or false to determine if a user has access to a controller action.
def update?
(user && user.role == 'admin') || (user && record.users.pluck(:id).include?(user.id)) || (user && user.id == record.owner.id)
end
def show?
(user.present? && user.admin?) or not record.hide?
end
def premium?
user.admin? or user.premium?
end
def edit?
end
end
我的模型
class Wiki < ActiveRecord::Base
belongs_to :user
has_many :collaborations, dependent: :destroy
has_many :users, through: :collaborations
def owner
user
end
def collaborators
users
end
validates :title, length: { minimum: 5 }, presence: true
validates :body, length: { minimum: 20 }, presence: true
end
class User < ActiveRecord::Base
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable, :confirmable
has_many :wikis
has_many :collaborations
has_many :cowikis, through: :collaborations, source: :wiki
after_initialize :init
def admin?
role == 'admin'
end
def premium?
role == 'premium'
end
def standard?
role == 'standard'
end
private
def init
if self.new_record? && self.role.nil?
self.role = 'standard'
end
end
end
class Collaboration < ActiveRecord::Base
belongs_to :user
belongs_to :wiki
end
維基控制器
class WikisController < ApplicationController
def index
@wikis = policy_scope(Wiki)
# authorize @wikis
end
def show
@wiki = Wiki.find(params[:id])
authorize @wiki
end
def new
@wiki = Wiki.new
authorize @wiki
end
def create
@wiki = Wiki.new(wiki_params)
authorize @wiki
if @wiki.save
flash[:notice] = "Post was saved."
redirect_to @wiki
else
flash[:error] = "There was an error saving the post. Please try again."
render :new
end
end
def edit
@user = current_user
@users = User.all
@wiki = Wiki.find(params[:id])
authorize @wiki
end
def update
@wiki = Wiki.find(params[:id])
authorize @wiki
@wiki.collaborators = params[:wiki][:user_ids]
if @wiki.update_attributes(wiki_params)
flash[:notice] = "Post was updated."
redirect_to @wiki
else
flash[:error] = "There was an error saving the post. Please try again."
render :edit
end
end
def destroy
@wiki = Wiki.find(params[:id])
authorize @wiki
title = @wiki.title
if @wiki.destroy
flash[:notice] = "\"#{title}\" was deleted successfully."
redirect_to wikis_path
else
flash[:error] = "There was an error deleting the wiki."
render :show
end
end
private
def wiki_params
params.require(:wiki).permit(:title, :body, :hide)
end
end
我希望你是不是不知所措的代碼,但我想提供儘可能多的信息成爲可能。
感謝您的幫助!
哦,這是最有可能的違規代碼,但我包括上下文的一切。
scope.joins(:collaborations).where("hide = :hide or user_id = :owner_id or collaborations.user_id = :collaborator_id", {hide: false, owner_id: user.id, collaborator_id: user.id})
萬一有人正在做一個大的查詢不同的表長範圍內沒有返回預期值。我必須將範圍分爲2(一個用於本地和另一個連接)。我確信有一個更優雅的方式來做到這一點,但這是我的工作代碼。 '(scope.where(「hide =:hide or wikis.user_id =:owner_id」,{hide:false,owner_id:user.id})+ scope.joins(:collaborations).where(「collaborations.user_id =:collaborator_id 「,{collaborator_id:user.id}))。uniq' – 2014-12-02 23:46:14