RailsCasts Pro episodes are now free!

Learn more or hide this

Recent Comments

Avatar

A very similar but easier DSL is http://github.com/AnthonyCaliendo/acts_without_database

Avatar

Woooo that's THE plugin 2009 ! ;) I love it.

I facing a small problem (for me).
 
In my UserController I have load_and_authorize_resource and

def edit
 @user = current_user
end

And of course I get a exception when a non authenticate user try to access to /users/:id/edit because it's trying to load the user in load_and_authorize_resource.

So where is my mistake ? :S
Is it not possible to check the right before loading the ressources into load_and_authorize_resource ?

Cancan is so great and fast to implement !!! :)

Thanks

Avatar

Anyone have any experience doing dynamic selects menus with very large numbers of option data? I've tried just JS and Ajax and both options are very slow on the first change. My first select has about 700 options, the second over 5000.

Avatar

Re: my previous post ( RnR Tom Dec 22, 2009 at 17:41)

A simple solution is available at:
http://wiki.github.com/ryanb/cancan/authorization-for-namespaced-controllers

moderator edit: Jul 13, 2011 [link]

Avatar

I need the same..
<< Is it possible to have a text field associated with each checkbox? What if the form creates an entry in the join table, but also should set a property in the jointable/join object itself? As an example, there is a free form text field for notes on the choice made by marking the checkbox.>>
Thank you

Avatar

Great plugin! However, I am having trouble using it on a controller without a companion model. For instance, I have a Calendar controller that builds and displays a calendar but there is not Calendar model for CanCan to lock onto. So I'm getting a "uninitialized constant" error when it tries to create a Calendar model.

I realize that I should probably not be calling "load_and_authorize_resource" but I'm not sure how else to get CanCan to secure the controller. Any tips on using CanCan without a model?

Avatar

Or you simply use the activerecord-tableless gem, which does the same basically ;)

Avatar

Hi Ryan,

There is one issue.

When you are redirecting to PayPal sandbox for Payment, you are not showing the amount which User is going to PAY ?

How can we show the AMOUNT on PayPal site which user is going to PAY ?

Thanks,
Bijesh

Avatar

Thx from newbee`s. :)

Avatar

here is lot of console trip n trick in rails

http://madhukaudantha.blogspot.com/2009/12/ruby-on-rails-part-3-console-tips.html

Avatar

ROLES.index(role) mabye return nil,so:

def roles=(roles)
    self.roles_mask = roles.inject(0) do |bit, role|
      1 << (ROLES.index(role) || -1) | bit
    end
  end
  
  def roles
    ROLES.select { |role| 1 << ROLES.index(role) & self.roles_mask > 0 }
  end
  
  named_scope :with_role, lambda { |role| {:conditions => "roles_mask & #{1 << (ROLES.index(role.to_s) || -1)} > 0"} }

Avatar

also check out bitmask_attributes: http://github.com/amiel/bitmask_attributes

Avatar

I like the idea of declarative authorization and I plan to implement it on my front-end application. However I feel that CanCan makes one incorrect and oversimplifying assumption: that (for example) the :update action applied to an object in one controller is the same as :update applied via a different controller.

Of course I am talking about the case of MyObjectsController vrs Admin::MyObjectsController.

I am sold on using separate Admin:: controllers due to vast differences in the interface for admin/non-admin usage. That leaves me needing to authorize actions based not just on the model and user (as CanCan seems to do,) but also on what controller is selected.

Am I missing something? Have I overlooked a simple way to use CanCan's ability definitions to limit actions by controller?

Avatar

So what's the point for this? Simply encapsulating validations in a model? In that case, wouldn't it be easy to just no call the save method and that's it? It's surely less code.

Avatar

Woops... didn't read all the comments. The original author already pointed this out.

Avatar

Or you could use:

http://github.com/remvee/active_form

Which is the same thing sitting conveniently in your /lib
plus its properly tested!

thanks for the episode.

Avatar

As far as validations, would Rails 3 improve this type of code?

Something like this perhaps?

class Recommendation
  include ActionModel::Validations

  attr_accessor :from_email
  validates_presense_of :from_email
end

An overview of some Rails 3 things (like the new routing) might be nice. There has been a frenzy of commits recently. Maybe they are gearing up for a RC, one year exactly from the announcement of the merge...

Avatar

Thanks for the great screencast, Ryan.
Note:
From Cucumber 0.4.5 and onwards you will also need to install the 'cucumber-rails' gem, or else 'script/generate cucumber' will fail.

Avatar

@zizo: whatever object you're calling is nil, try adding something like:
@user = User.new
to your controller. That helped me when I had the same error with my @user object.

Avatar

Hey, I love your site, and the tutorials are so helpful.
I'm trying to implement this project, but I'm running into error after error. I'm just a newbie, could you help me?
Here's the error I'm currently stuck on:
Authlogic::Session::Activation::NotActivatedError in HomepageController#home

You must activate the Authlogic::Session::Base.controller with a controller object before creating objects

Any suggestions?

Avatar

@Ryan:

Thanks for the episode!

Still, I believe this may soon become obsolete with the work being done in the ActiveModel project, which extracts validations, callbacks, etc. from ActiveRecord and ActiveModel.

Generally, I prefer a plain Ruby class whenever I need a tableless model. It's also good practice if you want to move towards NoSQL design and storage.

@Bjarki:

A good reason to store searches in your database might be logging, especially of empty searches (i.e. those returning no results).

Also, you could investigate collaborative filtering and provide automated recommendations based on previous searches.

Another plus comes form the url generated when creating a search. This url could be emailed and reused and you'd know how those visits are all related.

Hope that makes sense.

Avatar

Ryan - another great screencast - thanks!

I thought I'd point out James Golick's latest tool - FriendlyORM.
It's similar in concept to what you cover here, but packaged up neatly with a few additional features.
Check it at http://github.com/jamesgolick/friendly

Avatar

very useful screencast. thanks.

Avatar

I get : Called id for nil, which would mistakenly be 4 -- if you really wanted the id of nil, use object_id.

I can't find how solve this problem.

Avatar

Ryan, we are waiting for MongoDB railscast :) Please make us happy!

Avatar

Thanks for covering this, Ryan. Another great episode :-) Keep up the good work!

Avatar

Hello Ryan

great episode as always! :)

I am doing an application that requires multi-field search, you said in the episode that you always store user submitted information in the database. What would be the reason for storing searches in a database? I am asking because I am struggling with the concept of having table-less search or not.

Avatar

Almost exactly the same but also does the before and after callbacks:

http://github.com/remvee/active_form

Avatar

:member => {:recommend => [:any]}

No need for table, model, controller. Just a little action to the articles controller.

Avatar

Hi there,
Great cast again!
Like Ryan, I also researched the topic on table-less models about two months ago. While there are other solutions, I too chose the one Ryan liked most. Here's my implementation:
# Define an abstract base class for Tableless ActiveRecord models:
# and then use it like that:
# class Foo < TablelessModel
# column :bar, :string
# validates_presence_of :bar
# end
class TablelessModel < ActiveRecord::Base
  def self.columns
    @columns ||= [];
  end

  def self.column(name, sql_type = nil, default = nil, null = true)
    columns << ActiveRecord::ConnectionAdapters::Column.new(name.to_s, default, sql_type.to_s, null)
  end

  # Override the save method to prevent exceptions.
  def save(validate = true)
    validate ? valid? : true
  end
end

I use it in a bit different way though: I have a base model class called TablelessModel and inherit from it whenever needed.
I needed table-less models because in my applications I frequently have some more complicated reports, which need more complex SQL queries. Since the SQL queries etc belong in the models, I started implementing them as (class or instance) methods in the models. But I didn't like cluttering my models with code that sometimes doesn't belong there, like some find_by_sqls needed by some report. So I implemented my models to deal with the DB tables/resources and wherever needed, I implemented table-less models to hold the report SQL queries and other logic.
I'm writing this as a possible use case of this techinque, although my own table-less models often do have to deal with the database, just not with an existing table.

Avatar

Very cool. I'm playing with mongodb on a new project at the moment, any chance you plan on looking into any NoSQL stuff?

Thanks again Ryan!

Avatar

Realy a great cast !
Why not updated your cast #124 (Beta invitation) for authlogic ? :)

And what's about a other onem "How to add a validation email for authlogic" ? Would be great.

So any way, thanks a lot for your cast !

Avatar

"Not to mention removing the coupling between the database and the code."

You keep mentioning this over and over, but I don't see how the bitmask approach removes the coupling. All it does is introduce a different kind of coupling, one which is much harder to see than going to a join model and roles table: the precise number that contains the bitmask is COMPLETELY coupled with the array entries inside the ROLES constant.

Changing the latter breaks everything, unless you never remove an entry and only strictly append new entries to the end (you mention that).

This is one of those "clever" solutions that will only cause you pain later on when you've forgotten what you did and why (or your teammates will break it for you :-).

Avatar

What I want to know is if the action name is "update_article" instead of "update", the following code can still work?
<% if can? :update_article, @article %>
 <%= link_to "Edit", edit_article_path(@article) %>
<% end %>

Avatar

hi i wanna ask that
in this program can we show user's article..what i mean when we login can we just see the article who logins..if its possible how we can do it

Avatar

Ryan B has a set of sample code for this on github:
http://github.com/ryanb/complex-form-examples

This goes into more detail including show, index, edit, etc.

Avatar

hi ryan,
first thanks for the cancan.
question, in your example there are multiple blogs/subdomains, can i set up cancan where a user can have different roles depending on the group/blog/subdomain he/she is a member of?

to brute force this, i would have a user, group, and groupmembership table where groupmembership table would contain user_id, group_id, and role_id. can cancan make this easier?

thanks!

Avatar

Ok, sorry. After spending some time going through the source I found that I can just define permission_denied on my controller and it will be called and I can do whatever I want! Problem solved!

Avatar

Surely there are much better ways than this:

    class ApplicationController < ActionController::Base
        around_filter :authorize_redirect
        def authorize_redirect
            yield
            if response.body == "You are not allowed to access this action."
                response.redirect('/login', 550)
            end
        end
    end

but the authorization magick has already rendered, so I cannot render or redirect :(

Avatar

Hi Ryan!

Thanks for doing a screencast on this. I haven't had the time to dig deep into CanCan but from what I saw earlier it seemed very nice. Now, after watching this video it will definitely be my main authorization tool! I really like it's simplicity, productivity and approach to handling authorization.

I tried it out and it works fantastic. I have one question though. I noticed the ability.rb file could become quite long, depending on the amount of roles and models you want to authorize. Do you have any recommendation (or would you not recommend it) to put each "role" in it's own file? Like maybe: lib/roles/user.rb moderator.rb admin.rb etc. and then load them in? If you would separate them, how would you organize this? (just looking for some conventions) ;)

Thanks again.
I am looking forward to using this in my future applications!

Avatar

Is there a way to customize the message or do a redirect instead of just sending "You are not allowed to access this action." if authorization fails?

Avatar

Before considering PayPal, consider this:

http://blog.apparentsoft.com/business/124/is-paypal-good-for-your-microisv-business-a-short-paypal-horror-story/

Avatar

Before considering PayPal, consider this:

http://blog.apparentsoft.com/business/124/is-paypal-good-for-your-microisv-business-a-short-paypal-horror-story/

Avatar

Before considering PayPal, consider this:
http://blog.apparentsoft.com/business/124/is-paypal-good-for-your-microisv-business-a-short-paypal-horror-story/

Avatar

Before considering PayPal, consider this: http://blog.apparentsoft.com/business/124/is-paypal-good-for-your-microisv-business-a-short-paypal-horror-story/

Avatar

Hi, for those who have still problem with paperclip on windows and are still getting error:
"not recognized by the 'identify' command." and the solution: http://blog.jonathanhinson.com/2009/04/27/getting-paperclip-working-in-windows/ does not work:

I've reinstalled ruby with "http://rubyforge.org/frs/download.php/66871/rubyinstaller-1.8.6-p383-rc1.exe", uninstall imagemagick and install imagemagick 6.5.8-6 q16 and nothing more and it works! No more errors.
Hope it helps..

H.

Avatar

Okay, you made me fall in love with Declarative Authorization, and I got it working. So I have three questions about CanCan.
  
1.) It strikes me that CanCan is very similar to DA. What are the key 2 differences between CanCan and DA? What does 'heavy' mean?

2.) You showed us two controllers: comments & articles. I would love to see the users controller and see if you are able to use the current_user method there. I had to turn off the auto-model-loading functionality in my user controller when using DA.

3.) In comment 29 of episode 188 Jochen Kempf shared a way to 'control non-action related content'. Does CanCan have a solution for this?