5 Stimmen

Rails-Autorisierung mit CanCan-Problem

In meiner Rails-App habe ich AuthLogic und CanCan implementiert. Wenn ich jedoch versuche, herauszufinden, ob der Benutzer einen Artikel verwalten kann (prüft, ob er Eigentümer über die article.user_id ist) mit CanCan stoße ich auf Probleme. Dies sollte einfach sein, ich weiß nicht, was ich falsch mache.

Benutzer has_many Artikel

class Ability
    include CanCan::Ability

    def initialize(user)
        user ||= User.new

        can :read, :all
        can :manage, Article do |article|
           article.user_id == user.id
        end
    end         
end

Ich erhalte die folgende Fehlermeldung, wenn ich /articles/index aufrufe

undefined method `user' for #<Array:0x1035c5158>
Extracted source (around line #15):

12:         <td><%= article.created_at %></td>
13:         <td><%= article.user.login %></td>  
14:         <td><%= link_to 'View', article %></td>
15:     <% if can? :manage, article %>  
16:         <td><%= link_to 'Edit', edit_article_path(article) %></td>
17:     <% end %>
18:     <% if can? :manage, article %>  

app/models/ability.rb:9:in `try'
app/models/ability.rb:9:in `initialize'
cancan (1.3.4) lib/cancan/can_definition.rb:101:in `call'
cancan (1.3.4) lib/cancan/can_definition.rb:101:in `call_block'
cancan (1.3.4) lib/cancan/can_definition.rb:29:in `matches_conditions?'
cancan (1.3.4) lib/cancan/ability.rb:54:in `can?'
authlogic (2.1.6) lib/authlogic/session/password.rb:127:in `detect'
cancan (1.3.4) lib/cancan/ability.rb:53:in `each'
cancan (1.3.4) lib/cancan/ability.rb:53:in `detect'
cancan (1.3.4) lib/cancan/ability.rb:53:in `can?'
cancan (1.3.4) lib/cancan/controller_additions.rb:228:in `can?'
actionpack (3.0.0) lib/abstract_controller/helpers.rb:55:in `send'
actionpack (3.0.0) lib/abstract_controller/helpers.rb:55:in `can?'
app/views/articles/_articles.html.erb:15:in `_app_views_articles__articles_html_erb__1624837607_2174751840_1924990'
app/views/articles/_articles.html.erb:8:in `each'
app/views/articles/_articles.html.erb:8:in `_app_views_articles__articles_html_erb__1624837607_2174751840_1924990'
actionpack (3.0.0) lib/action_view/template.rb:135:in `send'
actionpack (3.0.0) lib/action_view/template.rb:135:in `render'
activesupport (3.0.0) lib/active_support/notifications.rb:54:in `instrument'
actionpack (3.0.0) lib/action_view/template.rb:127:in `render'
actionpack (3.0.0) lib/action_view/render/partials.rb:294:in `render_partial'
actionpack (3.0.0) lib/action_view/render/partials.rb:223:in `render'
activesupport (3.0.0) lib/active_support/notifications.rb:52:in `instrument'
activesupport (3.0.0) lib/active_support/notifications/instrumenter.rb:21:in `instrument'
activesupport (3.0.0) lib/active_support/notifications.rb:52:in `instrument'
actionpack (3.0.0) lib/action_view/render/partials.rb:221:in `render'
actionpack (3.0.0) lib/action_view/render/partials.rb:334:in `_render_partial'
actionpack (3.0.0) lib/action_view/render/rendering.rb:31:in `render'
app/views/articles/index.html.erb:5:in `_app_views_articles_index_html_erb___1319251192_2174766940_0'
actionpack (3.0.0) lib/action_view/template.rb:135:in `send'
actionpack (3.0.0) lib/action_view/template.rb:135:in `render'
activesupport (3.0.0) lib/active_support/notifications.rb:54:in `instrument'
actionpack (3.0.0) lib/action_view/template.rb:127:in `render'
actionpack (3.0.0) lib/action_view/render/rendering.rb:59:in `_render_template'
activesupport (3.0.0) lib/active_support/notifications.rb:52:in `instrument'
activesupport (3.0.0) lib/active_support/notifications/instrumenter.rb:21:in `instrument'
activesupport (3.0.0) lib/active_support/notifications.rb:52:in `instrument'
actionpack (3.0.0) lib/action_view/render/rendering.rb:56:in `_render_template'
actionpack (3.0.0) lib/action_view/render/rendering.rb:26:in `render'
actionpack (3.0.0) lib/abstract_controller/rendering.rb:114:in `_render_template'
actionpack (3.0.0) lib/abstract_controller/rendering.rb:108:in `render_to_body'
actionpack (3.0.0) lib/action_controller/metal/renderers.rb:47:in `render_to_body'
actionpack (3.0.0) lib/action_controller/metal/compatibility.rb:55:in `render_to_body'
actionpack (3.0.0) lib/abstract_controller/rendering.rb:101:in `render_to_string'
actionpack (3.0.0) lib/abstract_controller/rendering.rb:92:in `render'
actionpack (3.0.0) lib/action_controller/metal/rendering.rb:17:in `render'
actionpack (3.0.0) lib/action_controller/metal/instrumentation.rb:40:in `render'
activesupport (3.0.0) lib/active_support/core_ext/benchmark.rb:5:in `ms'
/opt/local/lib/ruby/1.8/benchmark.rb:308:in `realtime'
activesupport (3.0.0) lib/active_support/core_ext/benchmark.rb:5:in `ms'
actionpack (3.0.0) lib/action_controller/metal/instrumentation.rb:40:in `render'
actionpack (3.0.0) lib/action_controller/metal/instrumentation.rb:78:in `cleanup_view_runtime'
activerecord (3.0.0) lib/active_record/railties/controller_runtime.rb:15:in `cleanup_view_runtime'
actionpack (3.0.0) lib/action_controller/metal/instrumentation.rb:39:in `render'
actionpack (3.0.0) lib/action_controller/metal/implicit_render.rb:10:in `default_render'
actionpack (3.0.0) lib/action_controller/metal/implicit_render.rb:5:in `send_action'
actionpack (3.0.0) lib/abstract_controller/base.rb:150:in `process_action'
actionpack (3.0.0) lib/action_controller/metal/rendering.rb:11:in `process_action'
actionpack (3.0.0) lib/abstract_controller/callbacks.rb:18:in `process_action'
activesupport (3.0.0) lib/active_support/callbacks.rb:440:in `_run__704842227__process_action__199225275__callbacks'
activesupport (3.0.0) lib/active_support/callbacks.rb:409:in `send'
activesupport (3.0.0) lib/active_support/callbacks.rb:409:in `_run_process_action_callbacks'
activesupport (3.0.0) lib/active_support/callbacks.rb:93:in `send'
activesupport (3.0.0) lib/active_support/callbacks.rb:93:in `run_callbacks'
actionpack (3.0.0) lib/abstract_controller/callbacks.rb:17:in `process_action'
actionpack (3.0.0) lib/action_controller/metal/instrumentation.rb:30:in `process_action'
activesupport (3.0.0) lib/active_support/notifications.rb:52:in `instrument'
activesupport (3.0.0) lib/active_support/notifications/instrumenter.rb:21:in `instrument'
activesupport (3.0.0) lib/active_support/notifications.rb:52:in `instrument'
actionpack (3.0.0) lib/action_controller/metal/instrumentation.rb:29:in `process_action'
actionpack (3.0.0) lib/action_controller/metal/rescue.rb:17:in `process_action'
actionpack (3.0.0) lib/abstract_controller/base.rb:119:in `process'
actionpack (3.0.0) lib/abstract_controller/rendering.rb:40:in `process'
actionpack (3.0.0) lib/action_controller/metal.rb:133:in `dispatch'
actionpack (3.0.0) lib/action_controller/metal/rack_delegation.rb:14:in `dispatch'
actionpack (3.0.0) lib/action_controller/metal.rb:173:in `action'
actionpack (3.0.0) lib/action_dispatch/routing/route_set.rb:62:in `call'
actionpack (3.0.0) lib/action_dispatch/routing/route_set.rb:62:in `dispatch'
actionpack (3.0.0) lib/action_dispatch/routing/route_set.rb:27:in `call'
rack-mount (0.6.13) lib/rack/mount/route_set.rb:148:in `call'
rack-mount (0.6.13) lib/rack/mount/code_generation.rb:93:in `recognize'
rack-mount (0.6.13) lib/rack/mount/code_generation.rb:68:in `optimized_each'
rack-mount (0.6.13) lib/rack/mount/code_generation.rb:92:in `recognize'
rack-mount (0.6.13) lib/rack/mount/route_set.rb:139:in `call'
actionpack (3.0.0) lib/action_dispatch/routing/route_set.rb:492:in `call'
actionpack (3.0.0) lib/action_dispatch/middleware/best_standards_support.rb:17:in `call'
actionpack (3.0.0) lib/action_dispatch/middleware/head.rb:14:in `call'
rack (1.2.1) lib/rack/methodoverride.rb:24:in `call'
actionpack (3.0.0) lib/action_dispatch/middleware/params_parser.rb:21:in `call'
actionpack (3.0.0) lib/action_dispatch/middleware/flash.rb:182:in `call'
actionpack (3.0.0) lib/action_dispatch/middleware/session/abstract_store.rb:149:in `call'
actionpack (3.0.0) lib/action_dispatch/middleware/cookies.rb:287:in `call'
activerecord (3.0.0) lib/active_record/query_cache.rb:32:in `call'
activerecord (3.0.0) lib/active_record/connection_adapters/abstract/query_cache.rb:28:in `cache'
activerecord (3.0.0) lib/active_record/query_cache.rb:12:in `cache'
activerecord (3.0.0) lib/active_record/query_cache.rb:31:in `call'
activerecord (3.0.0) lib/active_record/connection_adapters/abstract/connection_pool.rb:355:in `call'
actionpack (3.0.0) lib/action_dispatch/middleware/callbacks.rb:46:in `call'
activesupport (3.0.0) lib/active_support/callbacks.rb:415:in `_run_call_callbacks'
actionpack (3.0.0) lib/action_dispatch/middleware/callbacks.rb:44:in `call'
rack (1.2.1) lib/rack/sendfile.rb:107:in `call'
actionpack (3.0.0) lib/action_dispatch/middleware/remote_ip.rb:48:in `call'
actionpack (3.0.0) lib/action_dispatch/middleware/show_exceptions.rb:46:in `call'
railties (3.0.0) lib/rails/rack/logger.rb:13:in `call'
rack (1.2.1) lib/rack/runtime.rb:17:in `call'
activesupport (3.0.0) lib/active_support/cache/strategy/local_cache.rb:72:in `call'
rack (1.2.1) lib/rack/lock.rb:11:in `call'
rack (1.2.1) lib/rack/lock.rb:11:in `synchronize'
rack (1.2.1) lib/rack/lock.rb:11:in `call'
actionpack (3.0.0) lib/action_dispatch/middleware/static.rb:30:in `call'
railties (3.0.0) lib/rails/application.rb:168:in `call'
railties (3.0.0) lib/rails/application.rb:77:in `send'
railties (3.0.0) lib/rails/application.rb:77:in `method_missing'
railties (3.0.0) lib/rails/rack/log_tailer.rb:14:in `call'
rack (1.2.1) lib/rack/content_length.rb:13:in `call'
rack (1.2.1) lib/rack/handler/webrick.rb:52:in `service'
/opt/local/lib/ruby/1.8/webrick/httpserver.rb:104:in `service'
/opt/local/lib/ruby/1.8/webrick/httpserver.rb:65:in `run'
/opt/local/lib/ruby/1.8/webrick/server.rb:173:in `start_thread'
/opt/local/lib/ruby/1.8/webrick/server.rb:162:in `start'
/opt/local/lib/ruby/1.8/webrick/server.rb:162:in `start_thread'
/opt/local/lib/ruby/1.8/webrick/server.rb:95:in `start'
/opt/local/lib/ruby/1.8/webrick/server.rb:92:in `each'
/opt/local/lib/ruby/1.8/webrick/server.rb:92:in `start'
/opt/local/lib/ruby/1.8/webrick/server.rb:23:in `start'
/opt/local/lib/ruby/1.8/webrick/server.rb:82:in `start'
rack (1.2.1) lib/rack/handler/webrick.rb:13:in `run'
rack (1.2.1) lib/rack/server.rb:213:in `start'
railties (3.0.0) lib/rails/commands/server.rb:65:in `start'
railties (3.0.0) lib/rails/commands.rb:30
railties (3.0.0) lib/rails/commands.rb:27:in `tap'
railties (3.0.0) lib/rails/commands.rb:27
script/rails:6:in `require'
script/rails:6

Dies ist meine Ansicht:

<% if can? :manage, article %>  
    <td><%= link_to 'Edit', edit_article_path(article) %></td>
<% end %>
<% if can? :manage, article %>  
    <td><%= link_to 'Delete', article, :method => :delete %></td>
<% end %>

Hier ist mein Controller:

  def index
    @articles = Article.find(:all)      
  end

9voto

malclocke Punkte 5142

Ich bin mir nicht sicher, was genau die Ursache für Ihr Problem ist, aber ich habe festgestellt, dass ich oft nachsehen muss, ob nil bei der Verwendung eines Wertes, d.h. in Ihrem Beispiel:

can :manage, Article do |article|
  article && article.user_id == user.id
end

scheint es, dass in bestimmten Situationen das Blockargument nil

Nach Angaben von http://github.com/ryanb/cancan/wiki/defining-abilities-with-hashes Vielleicht gibt es einen saubereren Weg:

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

Ich würde diese Methode zuerst ausprobieren und sehen, wie es läuft.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X