Newbie Question about Custom Classes


#1

Sorry if this is a complete newbish question, but I’m trying to wrap
my head around creating custom classes in my rails webapp. I’m
normally a Java developer, but I figured I’d give RoR a try and see
how I like it, and whether it would be useful for production use with
a new client.

Anyways, what are the best practices for custom classes? Where and/or
how do I create and use them? Is there a tutorial somewhere?
Basically, here’s what I’m trying to do. I have an XML file in a
custom format that represents news articles. In my controller I’m
using REXML to read and parse that file (BTW, see my note at the end
of this email), and I want to encapsulate that into an “Article” type
class, with title, date, description, etc that I can then use in my
view.

How do I go about this? Where should I store the class? If someone
could point me to a tutorial or example of custom classes in a Rails
app, or give me a little hint how/where to start I’d really appreciate
it.

Thanks,

  • Brent

NOTE: I was having a terrible time with RoR giving me a “File not
found” error when calling File.new. It said the current directory was
my rails project directory root. I checked, rechecked, copied-pasted
the directory/file to make SURE it was there. It was! Turns out the
current directory is the config/ directory and NOT the project one as
reported.


#2

Am Montag, den 20.03.2006, 10:37 -0500 schrieb Brent J.:

using REXML to read and parse that file (BTW, see my note at the end
of this email), and I want to encapsulate that into an “Article” type
class, with title, date, description, etc that I can then use in my
view.

How do I go about this? Where should I store the class? If someone
could point me to a tutorial or example of custom classes in a Rails
app, or give me a little hint how/where to start I’d really appreciate
it.

I would suggest storing your Article model in the app/models directory
and adding a create_from_xml class method, or parse the xml in the
controller as you already do.


Norman T.

http://blog.inlet-media.de


#3

Thanks for the response. I was just thinking of doing this. But
here’s what I would normally do in Java. I’d create a News class, and
an Article class. The News class would read the XML and create an
array of Article classes.

So, should I create two models, one called News and one called
Articles? Is every custom class considered a model? What about some
utility class that really doesn’t fit as a model?

Thanks again,

  • Brent

#4

Thanks for the info! The parsing won’t be terribly complex (just
doing some xpath queries, etc) so I think I’ll use your suggestion.

In Java, for a class to be used it has to be in your classpath. How
does RoR figure out where the actual class is? Does it look under
your app/models (and controllers, views, etc) and lib directories?

Thanks again,

  • Brent

#5

Am Montag, den 20.03.2006, 10:57 -0500 schrieb Brent J.:

  • Brent

On 3/20/06, Norman T. removed_email_address@domain.invalid wrote:

I would suggest storing your Article model in the app/models directory
and adding a create_from_xml class method, or parse the xml in the
controller as you already do.

Ok, i’ll get a little bit deeper:

Classes, that hold data go into app/models. Classes that have nothing to
do with holding data, go into the lib directory.

If your parsing logic is not too complex, i would put it into the
Article class. If it is complex, put it as a separate class or module in
lib.

My suggestion for your Article class:

class Article

class methods

class < self
def build_from_xml
# parsing logic goes here returning an Array of Article objects
end
end
end

In your controller just do:

class NewsController < ApplicationController
def my_action
File.open(‘my_articles.xml’) do |file|
@articles = Article.build_from_xml(file.read)
end
end
end


Norman T.

http://blog.inlet-media.de


#6

Alright, I know I have to be doing something extremely noobish. But
I’ve created a simple class that has one method just as a test,
because RoR can’t seem to find the methods I put in the class. So
here’s the simplest example I could think of:

class Article
def blah
end
end

Yes, this does absolutely nothing. But if I try this in my controller:

Article.blah()

I get “undefined method `blah’ for #Article:0xb789bfbc”. It doesn’t
matter what I put into “blah” it just never sees it. It does,
however, see the article class. Do I have to do anything special, or
define the method another way so that it’s accessible from the
controller? It’s currently in app/models/article.rb.

Thanks,

  • Brent

#7

Am Montag, den 20.03.2006, 11:27 -0500 schrieb Brent J.:

In Java, for a class to be used it has to be in your classpath. How
does RoR figure out where the actual class is? Does it look under
your app/models (and controllers, views, etc) and lib directories?

Ruby has a loadpath. It is extended by Rails (1.0) using the following
method:

  def default_load_paths
    paths = ["#{root_path}/test/mocks/#{environment}"]

    # Then model subdirectories.
    # TODO: Don't include .rb models as load paths
    paths.concat(Dir["#{root_path}/app/models/[_a-z]*"])
    paths.concat(Dir["#{root_path}/components/[_a-z]*"])

    # Followed by the standard includes.
    # TODO: Don't include dirs for frameworks that are not used
    paths.concat %w(
      app
      app/models
      app/controllers
      app/helpers
      app/services
      app/apis
      components
      config
      lib
      vendor
      vendor/rails/railties
      vendor/rails/railties/lib
      vendor/rails/actionpack/lib
      vendor/rails/activesupport/lib
      vendor/rails/activerecord/lib
      vendor/rails/actionmailer/lib
      vendor/rails/actionwebservice/lib
    ).map { |dir| "#{root_path}/#{dir}" }.select { |dir|

File.directory?(dir) }
end

Files in this directories don’t have to be required explicitly (because
of some Ruby extensions made by rails), but files in subdirectories of
you loadpath, e.g. lib/my_library/myfile.rb must be required like this:

require ‘my_library/myfile’


Norman T.

http://blog.inlet-media.de


#8

That’s because you’ve defined an instance method but are trying to
call a class method. That’s not going to work, as you’ve noticed. With
the code as you’ve written it here, you can call it like this…

a = Article.new
a.blah

Tried that first, actually. I get the same result, undefined method.

…or, if you want to call it as a class method, you do like this…

class Article
def self.blah
end
end

Just tried that, but got the same message. I know I’ve missed
something hugely obvious somewhere. I wasn’t sure if the problem was
Ruby OR Rails related, but I looked at some examples and tutorials on
creating classes in Ruby and it looks pretty straight forward. So I
thought maybe there was something in Rails I had to do to get it to
work correctly.

Thanks,

  • Brent

#9

“Brent” == Brent J. removed_email_address@domain.invalid writes:

Alright, I know I have to be doing something extremely noobish.

Kind of, yes. It’s a Ruby thing rather than a Rails thing you’re
missing.

class Article
def blah
end
end

Yes, this does absolutely nothing. But if I try this in my controller:

Article.blah()

I get “undefined method `blah’ for #Article:0xb789bfbc”.

That’s because you’ve defined an instance method but are trying to
call a class method. That’s not going to work, as you’ve noticed. With
the code as you’ve written it here, you can call it like this…

a = Article.new
a.blah

…or, if you want to call it as a class method, you do like this…

class Article
def self.blah
end
end

…and then you can call Article.blah


Calle D. removed_email_address@domain.invalid
http://www.livejournal.com/users/cdybedahl/
“But that was in the gauzy realm of meat and oxygen, not this real
world
here on the screen.” – archbishopm, LiveJournal


#10

OK, here’s the deal. It turns out I’ve got some caching turned on or
something. I bounced Apache HTTPD and wham, it worked. I then added
a return to my blah function to return a string. I tried again and it
wasnt returning anything. I bounced the server again and it returned
the value I set. Seems as though it gets cached the first time it
runs then never changes again.

Thanks for the help,

  • Brent

#11

Am Montag, den 20.03.2006, 14:06 -0500 schrieb Brent J.:

work correctly.
What about what i suggested before:

class Article

class methods

class < self
def blah
end
end
end

Don’t forget to restart your Websever unless you are working in
development mode using webrick server.

Norman T.

http://blog.inlet-media.de


#12

It’s located in app/models. I was thinking it may be running in the
production environment, because there is a setting called
“config.cache_classes” which was set to true. But I tried setting
that to false and restarting and still get the same result.

  • Brent

#13

Where is your class file located?


– Tom M.