Creating common method in application ontroller

hi, guys,
I would like to define a common method in the application controller
because the other resources will use this method.

Scenario: I have 2 resources: Posts (for blogs) and Coupons.

Common method: is_owner_or_admin( object )

I have defined this method within the application controller as I
figured it’s akin the base class that the controllers for the
resources will inherit from.
I’m just testing the syntax call so, please don’t look at this from a
process design point of view :slight_smile:

application_controller.rb

class ApplicationController < ActionController::Base
protect_from_forgery

def is_owner_or_admin(obj)
  @part = Part.find(params[:id])
  @current_user = get_current_user

   if ( @current_user == nil )
     flash[:notice] = 'Access denied'
     redirect_to root_url
     return false
   elsif ( @current_user.is_admin or (@current_user.login ==

@part.created_by) )
return true
else
flash[:notice] = ‘Access denied’
redirect_to root_url
return false
end
end
end

I’m trying to call this method in each of the before_filter in the
resources (ie. Posts, Coupons).
So, in posts_controller.rb , I do:

class PostsController < ApplicationController
before_filter :authenticate_user!,
:except => [:index, :show, :send_message, :get_subcategories]

 ...

def show
    @post = Post.find(params[:id])
    :is_owner_or_admin(@post)

    respond_to do |format|
        format.html # show.html.erb
        format.xml  { render :xml => @post }
    end
end

end

Anyway, when I run the rails server or run “ruby -w
posts_controller.rb”, I get the following error:

/home/ct9a/projects/port_over_to_rails3/app/controllers/
posts_controller.rb:20: syntax error, unexpected ‘(’, expecting
keyword_end
:is_owner_or_admin(@post)
^

On 1 June 2011 11:36, ct9a [email protected] wrote:

Scenario: I have 2 resources: Posts (for blogs) and Coupons.

Common method: is_owner_or_admin( object )

I have defined this method within the application controller as I
figured it’s akin the base class that the controllers for the
resources will inherit from.

You might find it makes more sense as a method on the objects
themselves - it’s a bit more in the spirit of OO this way too, whereas
the “common method” in application_controller is a bit imperative.

So you can do stuff like:
coupon = Coupon.new
if coupon.is_owned_or_administered_by(current_user) # no need to
put the result of “get_common_user” in an instance variable - and
“common_user” is a bit more commonly used
# do your stuff here…
end

So, in posts_controller.rb , I do:

class PostsController < ApplicationController
before_filter :authenticate_user!,
:except => [:index, :show, :send_message, :get_subcategories]

def show
@post = Post.find(params[:id])
:is_owner_or_admin(@post)

Looks like you’re reinventing authorization processes - it would save
you some time if you looked at Aegis, CanCan and the like…

/home/ct9a/projects/port_over_to_rails3/app/controllers/
posts_controller.rb:20: syntax error, unexpected ‘(’, expecting
keyword_end
:is_owner_or_admin(@post)

well yes - symbols aren’t method calls.

You should really be looking at either doing:
@post.is_owner_or_admined_by(current_user)
or
current_user.owns_or_administers(@post)
which way round is your choice, and either way can be utilised in the
permissions model of your chosen authentication gem.

hi there, Michael,

Good evening :slight_smile:

I’m just trying to figure out how to make functions in the base class
(application controller) such that resources/objects inheriting from
the base class will be able to use them.

  1. I’ve actually got an existing application which has the method
    implemented individually (ie. is_owner_or_admin() is being implemented
    in posts_controller.rb and coupons_controller.rb).
  2. the purpose of this method is to return true if the current object
    is being accessed by its owner/creator OR by an admin user. Hence, I
    wanted to extract that functionality into a base class (ie. the
    application controller) and pass that method an object to evaluate.
  3. I am trying to port over a rails 2.3.8 application into rails 3. In
    rails 2.3.8, i was using authlogic but in my attempt to port it over
    to rails 3, i am using devise. I do not think device would have any
    functionality as described in the previous point (2) but i might just
    look at Aegis, CanCan and some others for reference.
  4. Your reply on “symbols aren’t method calls” is so right :slight_smile:

I think I might have figured out how to solve my initial problem :slight_smile:

Thank you :slight_smile:

Gordon Y.

But what happens when you’re not using a controller; maybe when you’re
at the console, or in a script? - then these methods wouldn’t be
available. They relate to the objects - so they should (on balance)
live there. If you think they should be in the application_controller
(or any individual controller) that’s probably the old procedural
programming habits showing their heads :slight_smile:

yeah, in some ways, that has shown some procedural programming trait (my
day
job sees me coding in both procedural and OO environments and my
arguments
to totally be rid of procedural programming have been knocked back
strongly
:frowning: ).

Yes, that is a valid point but given that the resources I deal with can
only
work in the web domain as the app i have here is very simple albeit I do
deal with applications that have deal with data on and offline (xml file
transfers and etc) :slight_smile:

Devise is for authentication (logging in), Aegis & CanCan are for
authorization (can a user, logged in or not, do this thing…) -
they’re very different problem domains.

Yep, you’re right, Michael :slight_smile:
For my own app, I have just simplified it to have 2 types of users
(ie. ‘admin’ and ‘regular’ types).
Hence, I done away with using authorization gems as it’s a simple
application :slight_smile:

Sweet. Nice discussion. Thank you :slight_smile:

Loving rails since ver 2.3.x and finding sanity in it,
Gordon Y. :slight_smile:

On 1 June 2011 12:36, ct9a [email protected] wrote:

hi there, Michael,

Good evening :slight_smile:

I’m just trying to figure out how to make functions in the base class
(application controller) such that resources/objects inheriting from
the base class will be able to use them.

well, you’ve done that already - any method you write in
application_controller is available to any class that inherits from
it.

  1. I’ve actually got an existing application which has the method
    implemented individually (ie. is_owner_or_admin() is being implemented
    in posts_controller.rb and coupons_controller.rb).

But what happens when you’re not using a controller; maybe when you’re
at the console, or in a script? - then these methods wouldn’t be
available. They relate to the objects - so they should (on balance)
live there. If you think they should be in the application_controller
(or any individual controller) that’s probably the old procedural
programming habits showing their heads :slight_smile:

  1. I am trying to port over a rails 2.3.8 application into rails 3. In
    rails 2.3.8, i was using authlogic but in my attempt to port it over
    to rails 3, i am using devise. I do not think device would have any
    functionality as described in the previous point (2) but i might just
    look at Aegis, CanCan and some others for reference.

Devise is for authentication (logging in), Aegis & CanCan are for
authorization (can a user, logged in or not, do this thing…) -
they’re very different problem domains.

Yep, agreed. Using rails and domolicious just reinstates my sanity (ie
OO
methodology) which I work with after my day job.

Seems what I have done in my rails 2.3.8 application was right all along
as
in, i declared the method for each resource and called the method within
the
resource’s object (ie. post.is_owner_or_admin and
coupon.is_owner_or_admin)
:slight_smile:

Cheers :smiley:

On 1 June 2011 13:10, Gordon Y. [email protected] wrote:

my arguments
to totally be rid of procedural programming have been knocked back strongly
:frowning: ).

You don’t fix that by still using procedural methods when you’re
working in Rails :wink:

Demonstrate the efficiencies of following OO methods, and there’s no
argument. There’s very few occasions when a procedural approach is
better. The smaller the app, the more important following the design
standards is, so you can change it quickly later - no client likes
hearing “we’ll have to rewrite the whole thing to do that…” when
they ask for a little extra functionality to a ‘simple’ site (I
know… I’ve had to say it in the past! :smiley:

Regards,

Out of curiosity what should one do if one wants to have a method
inherited
by all models? Does rails already have a file for adding methods to the
model base class? Or do we just ram our methods into ActiveModel and
call
it a day? I have run into almost the opposite scenario as the thread
starter. Mainly with certain integrity checks I’ve needed to perform.

Monkey patches are evil.
On Jun 4, 2011 3:42 AM, “Michael P.” [email protected] wrote:

On 3 June 2011 18:34, Kevin [email protected] wrote:

Out of curiosity what should one do if one wants to have a method
inherited


You received this message because you are subscribed to the Google G.
“Ruby on Rails: Talk” group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to
[email protected].
For more options, visit this group at
http://groups.google.com/group/rubyonrails-talk?hl=en.

On 3 June 2011 18:34, Kevin [email protected] wrote:

Out of curiosity what should one do if one wants to have a method inherited
by all models?

You can monkey patch Object or Class if you really want…

patch in environment.rb

class Object
def your_method
puts “my method is here”
end
end

console

o = AnyObject.new
=> #
o.your_method
my method is here
=> nil
String.your_method
my method is here
=> nil

On 3 June 2011 23:38, Gordon Y. [email protected] wrote:

On Jun 4, 2011 3:42 AM, “Michael P.” [email protected] wrote:

You can monkey patch Object or Class if you really want…

Monkey patches are evil.

“Evil” is a bit strong :slight_smile:

They can have a place. I’ve found it invaluable in the past to add a
patch for ActiveRecord::Errors to merge two error objects’ messages
together.

On 3 June 2011 18:34, Kevin [email protected] wrote:

Out of curiosity what should one do if one wants to have a method inherited
by all models? Does rails already have a file for adding methods to the
model base class? Or do we just ram our methods into ActiveModel and call
it a day? I have run into almost the opposite scenario as the thread
starter. Mainly with certain integrity checks I’ve needed to perform.

Can one derive a class for ActiveModel, put the common methods in
there, and then derive the models from that? I have not tried it.

Colin

Google seems to indicate that one may simply mixin (Is that the correct
Ruby
terminology.) parts of ActiveModel into any class as one sees fit. For
example:ActiveModel: Make Any Ruby Object Feel Like ActiveRecord
If memory about the way inheritance works in Ruby serves me we should be
able to do something like that, without even needing to derive from
ActiveModel directly. Though in the case of a Rails application one
would
probably just create a stub class that derives from ActiveRecord::Base
stick
the common methods in there and then subclass that class since
ActiveModel
does not include the database related functionality.

hi, Michael:)

they are evil when you have to decommission some gems that are no
longer
supported and change from one rails 2.3.x-1 to rails 2.3.x. I had that
in
the past about a year plus… Madness lol