Filesystem as a Model?

One of the projects that I’m working on creates and twiddles with a lot
of directories. In version 1, I did this all in the controllers, but
I’m beginning to think that the whole design would be cleaner in v2 if I
made the filesystem a model.

My plan for going about this would be to generate a model (Filesystem),
but create no migration for it, and then override all of the methods I’d
want to use in app/models/filesystem.rb

All of the directories are directly related to another model, so it’d
just be passing :id into the model functions. (unlock_dir, lock_dir,
create, destroy, etc)

Does this seem like a stupid solution? Is there a much better way that
I’m missing?

Thanks

On 4/24/07, Jonathan D. [email protected] wrote:

One of the projects that I’m working on creates and twiddles with a lot
of directories. In version 1, I did this all in the controllers, but
I’m beginning to think that the whole design would be cleaner in v2 if I
made the filesystem a model.

My plan for going about this would be to generate a model (Filesystem),
but create no migration for it, and then override all of the methods I’d
want to use in app/models/filesystem.rb

All of the directories are directly related to another model, so it’d
just be passing :id into the model functions. (unlock_dir, lock_dir,
create, destroy, etc)

Does this seem like a stupid solution? Is there a much better way that
I’m missing?

Well I think you might be abusing the abstraction. It might work, maybe
somebody has already implemented something similar successfully.

I think you were closer to a good representation the first time: do the
work in the controllers. Or better yet, farm the effort out to
controller
helpers or even something global like a plugin.

Ruby’s file processing and directory crawling methods are very powerful,
hiding them under a lot of inappropriate abstraction layers,
reimplementing
them as finders etc. just seems like the wrong thing to do. I think you
were right the first time.

However you will miss out on Model Validations, which is probably why
you thought of file system modeling?

On 4/25/07, Richard C. [email protected] wrote:

want to use in app/models/filesystem.rb

I think you were closer to a good representation the first time: do the
work in the controllers. Or better yet, farm the effort out to controller
helpers or even something global like a plugin.

Ruby’s file processing and directory crawling methods are very powerful,
hiding them under a lot of inappropriate abstraction layers, reimplementing
them as finders etc. just seems like the wrong thing to do. I think you
were right the first time.

I’ve written a lot of ‘heavy’ controllers and think the approach has
some advantages. It’s usually less work than coming up with a domain
layer with a clean/elegant interface, IMO, but it usually ends up
smelling a bit strange.

Imagine what happens if Jonathan wants to do a GUI or CLI -based port
of his app; new presentation layers would require new controllers, and
he’d have to rewrite, or at least copy+paste, his file system code for
each environment.
Granted, this doesn’t apply to most projects, but i still believe
there’s a maintainability issue.

The model directory is where all your other domain logic is kept, and
I don’t see any fundamental difference between AR backed and non-db
models, so why keep them apart…? If it’s app specific code, it really
doesn’t belong in a library.

You’d also get to unit test your classes easily, which is a big plus in
my book.

Regards,
Isak

Imagine what happens if Jonathan wants to do a GUI or CLI -based port
of his app; new presentation layers would require new controllers, and
he’d have to rewrite, or at least copy+paste, his file system code for
each environment.
Granted, this doesn’t apply to most projects, but i still believe
there’s a maintainability issue.

About half of the project is a daemon with no view, which is what led me
down this path. In version 1, I copied and pasted the code between the
controllers and the daemon, and I really want to avoid that in version
2.

Is it possible to have Models that aren’t decended from
ActiveRecord::Base? Conceptually, I’m definitely using the filesystem
as a model, and I’d really like to have a unified interface between the
web app and the daemon. There is also a very small number of actions
that I’ll need to do, and these are heavily shared between the daemon
and web app. I guess I could use a plugin, but that seems even more
hackish (from a design standpoint). I’m still not really sure what the
‘rails way’ is in these situations.

Is it possible to have Models that aren’t decended from ActiveRecord::Base?

Absolutely. In the project I’m currently working on, one of the models
is a small number of static objects, which are initialised from a YAML
template which is hardcoded within the model file itself. There is
another model which implements a concept of “groups”: the database has
no separate table for groups, but rather group memberships are
attributes of other model objects. So in this case this is a sort of
‘virtual’ model. For example, if you ask it for a list of all groups,
then what it actually does is a “select distinct(grp) from [other
model table]”.

Of course, if your model isn’t descended from ActiveRecord::Base, then
the API it exposes to the controllers may well be very different to
ActiveRecord, but since these are also your own controllers this isn’t
a problem.

The other way to have filesystem-backed models is to use ActiveRecord
with sqlite, but I don’t think that’s what you’re asking for :slight_smile:

Anyway, I’d say you should feel free to build your own non-AR model.
You then put logic as to what to do with the model in the
controllers.

This is assuming that your model is somehow “adding value” over basic
filesystem operations. If the API it provides is just “list files”,
“open file”, “delete file” then maybe the controller should use the
native IO methods for those. But even then, a thin model layer could
perform basic filename validation and restrict access to certain
directories.

Just my 2c… Brian.