كانكان لا يعرض عناصر الرؤية المعتمدة
-
26-09-2019 - |
سؤال
أحاول الحصول على بعض المصادقة/التفويض الأساسي مع Pintise/Cancan مع القضبان. بدلاً من استخدام أدوار مثل شاشة Ryan B والأمثلة الأخرى حولها أحاول القيام بشيء أساسي:
1 - يمكن للمستخدم تسجيل الدخول
2 - لا يمكن للمستخدم سوى تحرير/تدمير مقالاته الخاصة (بدون أدوار ، إما قمت بتسجيل الدخول ويمكنك إنشاء مقالات جديدة وتحرير/تدميرك أو يمكنك تسجيلها فقط ويمكنك رؤية المقالات وتسجيل الدخول فقط)
أنا أستخدم ابتكار للجزء الأول وهذا يعمل بشكل جيد ولكن لا يمكنني الحصول على الجزء الثاني مع كانان. لا تظهر روابط التحرير وتدمير المقالات عندما تقوم بتسجيل الدخول وما زال عنوان URL المباشر (على سبيل المثال/مقالات/3/تحرير) يسمح حتى لو كانت المقالة لمستخدم آخر.
لي ability.rb
هو
class Ability
include CanCan::Ability
def initialize(user)
user ||= User.new # guest user
if user.nil?
can :read, :all
else
# can :manage, :all #test - with this, all the edit/destroy links appear
can :manage, Article, :user_id == user
end
end
end
articles_controller.rb
:
class ArticlesController < ApplicationController
before_filter :authenticate_user!, :except => [:index, :show] # for Devise
load_and_authorize_resource
# GET /articles
# GET /articles.xml
def index
@articles = Article.all
respond_to do |format|
format.html # index.html.erb
format.xml { render :xml => @articles }
end
end
# GET /articles/1
# GET /articles/1.xml
def show
@article = Article.find(params[:id])
respond_to do |format|
format.html # show.html.erb
format.xml { render :xml => @article }
end
end
# GET /articles/new
# GET /articles/new.xml
def new
@article = Article.new
respond_to do |format|
format.html # new.html.erb
format.xml { render :xml => @article }
end
end
# GET /articles/1/edit
def edit
@article = Article.find(params[:id])
end
# POST /articles
# POST /articles.xml
def create
@article = Article.new(params[:article])
@article.user = current_user
respond_to do |format|
if @article.save
format.html { redirect_to(articles_path, :notice => 'Article was successfully created.') }
format.xml { render :xml => articles_path, :status => :created, :location => articles_path }
else
format.html { render :action => "new" }
format.xml { render :xml => @article.errors, :status => :unprocessable_entity }
end
end
end
# PUT /articles/1
# PUT /articles/1.xml
def update
@article = Article.find(params[:id])
respond_to do |format|
if @article.update_attributes(params[:article])
format.html { redirect_to(@article, :notice => 'Article was successfully updated.') }
format.xml { head :ok }
else
format.html { render :action => "edit" }
format.xml { render :xml => @article.errors, :status => :unprocessable_entity }
end
end
end
# DELETE /articles/1
# DELETE /articles/1.xml
def destroy
@article = Article.find(params[:id])
@article.destroy
respond_to do |format|
format.html { redirect_to(articles_url) }
format.xml { head :ok }
end
end
end
والمنظر الجزئي الذي يسرد المقالات _article_list.html.erb
:
<table>
<tr>
<th>Title</th>
<th>Description</th>
<th>User</th>
<th></th>
<th></th>
<th></th>
</tr>
<% @articles.each do |article| %>
<tr>
<td><%= article.title %></td>
<td><%= article.description %></td>
<td><%= article.user_id %></td>
<td><%= link_to 'Show', article %></td>
<% if can? :update, @article %>
<td><%= link_to 'Edit', edit_article_path(article) %></td>
<% end %>
<% if can? :destroy, @article %>
<td><%= link_to 'Destroy', article, :confirm => 'Are you sure?', :method => :delete %></td>
<% end%>
</tr>
<% end %>
</table>
مع هذا الإعداد ، لا تظهر الروابط تحرير/تدمير في العرض ما لم تكن هناك بطانية can :manage, :all
, ، حتى في can :manage, Article
لا يعمل. كما ذكرت أعلاه ، فإنه أيضًا لا يقيد الإجراءات الفعلية حيث يمكنك الارتباط بشكل مباشر بتحرير مقال ويسمح بذلك.
لست متأكدًا مما أفعله خطأ هنا. سيكون من الرائع الحصول على بعض المساعدة.
شكرا لك مقدما
جيسون
المحلول
تمكنت من حل مشكلتي. أقوم بإعادة ضبط بيئتي (RVM - Resintalled الأحجار الكريمة والأحجار الكريمة - Ruby 1.9.2 و Rails 3.0.0) وغيرت بعض الكود وجميع المشكلات التي كنت قد ذهبت بعيدًا (Redirect Loop ، عرض عناصر لا تتغير بناءً على تسجيل الدخول في ، لا تزال إجراءات وحدة تحكم غير مصرح بها يمكن السماح بها). لقد لصق ability.rb
, articles_controller.rb
, ، و _article_list.html.erb
.
ability.rb
:
class Ability
include CanCan::Ability
def initialize(user)
if user
can :create, Article
can :read, :all
can :update, Article, :user_id => user.id
can :delete, Article, :user_id => user.id
else
can :read, :all
end
end
end
أعتقد أنه من المنطقي الآن ولكن نظرًا لأن التحديث والحذف فقط كان من المفترض أن يكونوا لمقالات المستخدم الحالي ، فقد قمت بتقسيم عناصر Crud لتكون محددة.
articles_controller.rb
class ArticlesController < ApplicationController
before_filter :authenticate_user!, :except => [:index, :show]
# load_and_authorize_resource # RESTful automated CanCam authorization - excludes non RESTful
# GET /articles
# GET /articles.xml
def index
@articles = Article.all
authorize! :read, @articles
respond_to do |format|
format.html # index.html.erb
format.xml { render :xml => @articles }
end
end
# GET /articles/1
# GET /articles/1.xml
def show
@article = Article.find(params[:id])
authorize! :read, @article
respond_to do |format|
format.html # show.html.erb
format.xml { render :xml => @article }
end
end
# GET /articles/new
# GET /articles/new.xml
def new
@article = Article.new
authorize! :create, @article
respond_to do |format|
format.html # new.html.erb
format.xml { render :xml => @article }
end
end
# GET /articles/1/edit
def edit
@article = Article.find(params[:id])
authorize! :update, @article
end
# POST /articles
# POST /articles.xml
def create
@article = Article.new(params[:article])
@article.user = current_user
authorize! :create, @article
respond_to do |format|
if @article.save
format.html { redirect_to(articles_path, :notice => 'Article was successfully created.') }
format.xml { render :xml => articles_path, :status => :created, :location => articles_path }
else
format.html { render :action => "new" }
format.xml { render :xml => @article.errors, :status => :unprocessable_entity }
end
end
end
# PUT /articles/1
# PUT /articles/1.xml
def update
@article = Article.find(params[:id])
authorize! :update, @article
respond_to do |format|
if @article.update_attributes(params[:article])
format.html { redirect_to(@article, :notice => 'Article was successfully updated.') }
format.xml { head :ok }
else
format.html { render :action => "edit" }
format.xml { render :xml => @article.errors, :status => :unprocessable_entity }
end
end
end
# DELETE /articles/1
# DELETE /articles/1.xml
def destroy
@article = Article.find(params[:id])
@article.destroy
authorize! :delete, @article
respond_to do |format|
format.html { redirect_to(articles_url) }
format.xml { head :ok }
end
end
def by
@user = User.find(params[:id])
@articles = @user.articles
authorize! :read, @articles
end
end
load_and_authorize_resource
يعمل لكنني وضعت تفويضًا محددًا! خطوط في كل وحدة تحكم حيث لدي إجراء إضافي في الأسفل. كلاهما يعمل الآن.
لقد قمت بتحديث الإشارة إلى @Article إلى مقالة للإشارة إلى المقالة الحالية في القائمة في _article_list.html.rb
:
<table>
<tr>
<th>Title</th>
<th>Description</th>
<th>User</th>
<th></th>
<th></th>
<th></th>
</tr>
<% @articles.each do |article| %>
<tr>
<td><%= article.title %></td>
<td><%= article.description %></td>
<td><%= article.user_id %></td>
<td><%= link_to 'Show', article %></td>
<% if can? :update, article %>
<td><%= link_to 'Edit', edit_article_path(article) %></td>
<% end %>
<% if can? :delete, article %>
<td><%= link_to 'Destroy', article, :confirm => 'Are you sure?', :method => :delete %></td>
<% end %>
</tr>
<% end %>
</table>
كل العمل الآن. شكرًا للمساعدة هنا ونأمل أن يساعد هذا شخصًا آخر إذا واجهت هذه المشكلة.
نصائح أخرى
حالتك لمطابقة معرف المستخدم ليست صحيحة تمامًا. يجب أن يكون:
can :manage, Article, :user_id => user.id
يتم تعيين السمة التي تريد التحقق منها بالقيمة التي تريد التحقق منها.
أيضا ، أنت تتحقق user.nil?
عندما لا يمكن أن يكون لا شيء لأنك قمت للتو بتلقيته. (ربما أحد أعراض جربت الكثير من الأشياء!)
هل يعمل الصيد الخاص بك؟ إذا قمت بتوضيح العلبة: إدارة ، هل سيتمكن المستخدم من تحرير منشوره (إلى جانب الجميع بالطبع)؟
هل حاولت التغيير ، CAN: إدارة ، مقالة ،: user_id == المستخدم إلى
can :manage, Article do |article|
article.try(:user) == user
لم أتمكن مطلقًا من التحميل لتوضيح العمل- على الرغم من أنني أظن أنني كنت أفعل شيئًا خاطئًا. لمنع شخص ما من الوصول إلى عنوان URL مباشرة ، في إجراء تحرير مقالتك ، حاول إضافة هذا
unauthorized! if cannot? :edit, @article