Frage

Ich versuche, einige grundlegende Authentifizierung / Autorisierung zu erhalten mit devise / Cancan mit Rails. Anstatt um ich Rollen wie Ryan B Screencasts und andere Beispiele verwenden ich versucht, etwas Grundsätzliches zu tun:

1 - Ein Benutzer in
anmelden kann 2 - Ein Benutzer kann nur bearbeiten / zerstören ihre eigenen Artikel (keine Rollen, sind Sie entweder angemeldet und können neue Artikel und bearbeiten erstellen / zerstören Sie Ihre eigenen, oder du bist abgemeldet und Sie können nur Artikel und Login sehen)

Ich verwende devise für den ersten Teil und das funktioniert gut, aber ich kann nicht den zweiten Teil mit CanCan Arbeit bekommen. Die das Bearbeiten und zerstören Links für die Artikel erscheinen nicht, wenn Sie angemeldet sind und die direkte URL (z / articles / 3 / edit) erlaubt nach wie vor, auch wenn der Artikel für einen anderen Benutzer ist.

Meine ability.rb ist

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

und die Ansicht teilweise, dass die Listen Artikel _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>

Mit diesem Setup, das Bearbeiten / zerstören Links in der Ansicht nicht zeigen, es sei denn es gibt eine Decke can :manage, :all, tut auch can :manage, Article nicht Arbeit. Wie ich bereits erwähnt, es ist auch nicht die tatsächlichen Aktionen, wie Sie beschränken Artikel sind in der Lage zu Deep-Link direkt auf die Bearbeitung und erlaubt es.

Ich bin nicht sicher, was ich hier tue falsch. Es wäre toll, etwas Hilfe zu bekommen.

Vielen Dank im Voraus
Jason

War es hilfreich?

Lösung

konnte ich mein Problem lösen. Ich meine Umgebung zurückgesetzt (RVM - resintalled die Edelsteine ??und gemsets - Rubin 1.9.2 und Rails 3.0.0) und geänderte Änderungen sind auf protokollierten einen Teil des Codes und alle die Fragen, die ich habe wegging (Redirect Schleife, Ansichtselemente nicht auf der Grundlage in, nicht autorisierten Controller-Aktionen noch zulässig). Ich habe klebte ability.rb, articles_controller.rb und _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

Ich denke, es macht Sinn jetzt aber, da nur aktualisieren und löschen sollte für den aktuellen Benutzer Artikel sein, ich spaltete die CRUD Elemente aus spezifisch sein.

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 funktioniert, aber ich habe bestimmte authorise setzen! Zeilen in jeder Controller-Aktion, wie ich habe eine zusätzliche Maßnahme an der Unterseite. Beide jetzt arbeiten.

ich den Verweis auf @article zum Artikel aktualisiert, um den aktuellen Artikel in der Liste in _article_list.html.rb zu verweisen:

<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>

Alle arbeiten jetzt. Danke für die Hilfe hier und hoffentlich Dies wird helfen, jemand anderes aus, wenn sie in dieses Problem.

Andere Tipps

Ihr Zustand einen Benutzer-ID für den Abgleich ist nicht ganz richtig. Es sollte sein:

can :manage, Article, :user_id => user.id

Das Attribut, das Sie überprüfen wollen, auf den Wert, den Sie gegen überprüfen möchten abgebildet.

Auch Sie überprüfen für user.nil?, wenn es nicht gleich Null sein kann, weil Sie haben es gerade initialisiert. (Wahrscheinlich ein Symptom mit versucht, viele Dinge!)

Gibt es in Ihrem Fang Arbeit? Wenn Sie die Dose Kommentar-: verwalten,: alle Zeile wird ein Benutzer in der Lage sein, seinen / ihren Beitrag zu bearbeiten (zusammen mit allen anderen natürlich)

?

Haben Sie versucht, zu ändern, können: verwalten, Artikel,: user_id == Benutzer

can :manage, Article do |article|
 article.try(:user) == user

Ich habe nie in der Lage gewesen Last eine autorisieren zu bekommen, um arbeits obwohl ich vermute, dass ich etwas falsch mache. Um zu verhindern, jemand aus der URL direkt zugreifen, in Ihrem Artikel der Aktion bearbeitet, versuchen Sie, dies

 unauthorized! if cannot? :edit, @article
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top