ActiveScaffold init calls 'install' every time, even in production

1 view
Skip to first unread message

Don.M...@gmail.com

unread,
Aug 17, 2007, 1:04:00 PM8/17/07
to ActiveScaffold : Ruby on Rails plugin
It appears that the plugin copies the public files from the plugin dir
to the public
dir EVERYTIME the application is run
(from init.rb)

##
## Initialize the environment
##
require File.dirname(__FILE__) + '/environment'

##
## Run the install script, too, just to make sure
##
require File.dirname(__FILE__) + '/install'

This was causing a failure for me in production mode running under
Apache when files were attempted to be copied to public/stylessheets
and public/javascript, which are not writeable by the apache process,
since the directories were initially created under my userid.

In addition, it is inefficient. I think this needs to be fixed.
Other than that, ActiveScaffold is great.

Thanks,
Don McClean

Lance Ivy

unread,
Aug 17, 2007, 3:18:26 PM8/17/07
to actives...@googlegroups.com
Those files get copied every time in case there's a newer version than you have, so you don't have to run some update task whenever you update ActiveScaffold. It would probably be less efficient to run a file diff, or to maintain and check a per-file version. In your case maybe we just need a simple "rescue" statement? Hmm, but only if the file already exists, otherwise it should still throw an exception.

Don.M...@gmail.com

unread,
Aug 17, 2007, 5:27:09 PM8/17/07
to ActiveScaffold : Ruby on Rails plugin
Lance,
Thanks for responding so quickly.

It would seem that the files should only be copied when someone
does a plugin install/update to my application.

With respect to plugins, I think init.rb and install.rb should work
as:

# init.rb: Runs everytime the Rails app is started. Useful for mixing-
in a helper module so all your views can use it.

# install.rb: Runs one time only when the plugin is first installed.
Can be used to copy required files or to show installation
instructions.

So I think init.rb should not be calling install.rb

Thanks,
Don


On Aug 17, 2:18 pm, "Lance Ivy" <la...@cainlevy.net> wrote:
> Those files get copied every time in case there's a newer version than you
> have, so you don't have to run some update task whenever you update
> ActiveScaffold. It would probably be less efficient to run a file diff, or
> to maintain and check a per-file version. In your case maybe we just need a
> simple "rescue" statement? Hmm, but only if the file already exists,
> otherwise it should still throw an exception.
>

Lance Ivy

unread,
Aug 17, 2007, 5:33:16 PM8/17/07
to actives...@googlegroups.com
Right, so what should happen when ActiveScaffold's javascript and stylesheets get updated?

> > require File.dirname (__FILE__) + '/environment'

Don.M...@gmail.com

unread,
Aug 17, 2007, 5:58:17 PM8/17/07
to ActiveScaffold : Ruby on Rails plugin
Only when a user runs
script/plugin update active_scaffold

would any updated javascripts and stylesheets
should be copied to the public directory.


That way it is under my control. That is when
any updates would occur anyway as far as changes to files.

On Aug 17, 4:33 pm, "Lance Ivy" <la...@cainlevy.net> wrote:
> Right, so what should happen when ActiveScaffold's javascript and
> stylesheets get updated?
>

> > > > require File.dirname(__FILE__) + '/environment'

Lance Ivy

unread,
Aug 17, 2007, 6:04:56 PM8/17/07
to actives...@googlegroups.com
But `./script/plugin update active_scaffold` doesn't call an update.rb file, so how would ActiveScaffold know that was happening? And what if someone isn't using ./script/plugin? What if they're using Piston? Or they use svn directly, or unpackage the zip distributable?

Don.M...@gmail.com

unread,
Aug 19, 2007, 5:59:18 PM8/19/07
to ActiveScaffold : Ruby on Rails plugin
Ok, I give. :)
Here is a link to another developer who encountered the same problem
with activescaffold:

http://edseek.com/archives/2007/07/24/activescaffold-and-mongrel-death-in-production/

Thanks
Don

On Aug 17, 5:04 pm, "Lance Ivy" <la...@cainlevy.net> wrote:
> But `./script/plugin update active_scaffold` doesn't call an update.rb file,
> so how would ActiveScaffold know that was happening? And what if someone
> isn't using ./script/plugin? What if they're using Piston? Or they use svn
> directly, or unpackage the zip distributable?
>

Lance Ivy

unread,
Aug 19, 2007, 6:28:07 PM8/19/07
to actives...@googlegroups.com
I'll add the "rescue". Hopefully that should fix the startup problems.

Don.M...@gmail.com

unread,
Aug 19, 2007, 8:36:32 PM8/19/07
to ActiveScaffold : Ruby on Rails plugin
Ok, thanks

On Aug 19, 5:28 pm, "Lance Ivy" <la...@cainlevy.net> wrote:
> I'll add the "rescue". Hopefully that should fix the startup problems.
>

> On 8/19/07, Don.McCl...@gmail.com <Don.McCl...@gmail.com> wrote:
>
>
>
> > Ok, I give. :)
> > Here is a link to another developer who encountered the same problem
> > with activescaffold:
>

> >http://edseek.com/archives/2007/07/24/activescaffold-and-mongrel-deat...

Benjamin Allfree

unread,
Aug 20, 2007, 2:20:42 AM8/20/07
to actives...@googlegroups.com
I think Facebook doesn't allow JavaScript. It would be cool to use ActiveScaffold in there instead of Scaffold Extensions.

Any way to disable Ajax?

Lance Ivy

unread,
Aug 20, 2007, 12:05:04 PM8/20/07
to actives...@googlegroups.com
Completely? Might be hard. We consider the HTML mode to be a pretty raw fallback in case people don't have JavaScript enabled, but we just simply can't do the same things with just HTML. For example, embedded scaffolds won't stay embedded.

Benjamin Allfree

unread,
Aug 20, 2007, 4:59:27 PM8/20/07
to actives...@googlegroups.com
Scaffold Extensions might be a better option. Why try to be all things to all people ;)

Stephen Bannasch

unread,
Aug 22, 2007, 6:54:48 PM8/22/07
to actives...@googlegroups.com
At 3:04 PM -0700 8/17/07, Lance Ivy wrote:
But `./script/plugin update active_scaffold` doesn't call an update.rb file, so how would ActiveScaffold know that was happening? And what if someone isn't using ./script/plugin? What if they're using Piston? Or they use svn directly, or unpackage the zip distributable?

On 8/17/07, Don.M...@gmail.com <Don.M...@gmail.com> wrote:

Only when a user runs
script/plugin update active_scaffold

would any updated javascripts and stylesheets
should be copied to the public directory.


That way it is under my control. That is when
any updates would occur anyway as far as changes to files.

On Aug 17, 4:33 pm, "Lance Ivy" < la...@cainlevy.net> wrote:
> Right, so what should happen when ActiveScaffold's javascript and
> stylesheets get updated?

The behavior of AS (I'm using trunk) where it copies the assets from the plugin to public/ every time the plugin is initialized is also a problem for me.  I was learning AS and busy changing the css files (to make it look the way I wanted it to) and was confused about why my changes kept disappearing. I ended up adding my own frontend dir into the plugin folder, doing my edits there and restarting the server to see them -- very annoying.

If I am updating plugins using Piston or svn I expect to have read the documentation and know if I need to run something if there are assets that might need updating.

This is what happens when I update rails and prototype or scriptaculous have been updated. I need to run this rake task:

  rake rails:update:javascripts 

Which does this: "Update your javascripts from your current rails install".

So here's my patch which stops AS from copying the assets when it is initialized and adds these rake tasks (patch also attached to email). Patch is derived from code in install.rb and my changes are released as public domain.

Update Active Scaffold assets (javascripts/stylesheets/images) in  public/ from the plugin:

  rake active_scaffold:update

Update Active Scaffold images in public/images/ from the plugin:

  rake active_scaffold:update:images

Update Active Scaffold javascripts in public/javascripts/ from the plugin:

  rake active_scaffold:update:javascripts

Update Active Scaffold stylesheets in public/stylesheets/ from the plugin:

  rake active_scaffold:update:stylesheets

Index: tasks/active_scaffold.rake
===================================================================
--- tasks/active_scaffold.rake      (revision 0)
+++ tasks/active_scaffold.rake      (revision 0)
@@ -0,0 +1,42 @@
+namespace :active_scaffold do
+
+  desc "Update Active Scaffold assets (javascripts/stylesheets/images) in  public/ from the plugin"
+  task :update => [ "update:javascripts", "update:stylesheets", "update:images" ]
+
+  namespace :update do
+
+    def copy_files(source_path, destination_path, directory)
+      source, destination = File.join(directory, source_path), File.join(RAILS_ROOT, destination_path)
+      FileUtils.mkdir(destination) unless File.exist?(destination)
+      puts "Copied: #{Dir.glob(source+'/*.*').collect {|f| f.split(source+'/')[1]}.join(', ')} \n    to: #{destination}."
+      FileUtils.cp_r(Dir.glob(source+'/*.*'), destination)
+    end
+
+    def copy_asset_type(asset_type)
+      directory = File.join(File.dirname(__FILE__), '..')
+      available_frontends = Dir[File.join(directory, 'frontends', '*')].collect { |d| File.basename d }
+      path = "/public/#{asset_type}/active_scaffold"
+#      copy_files(path, path, directory)
+      available_frontends.each do |frontend|
+        source = "/frontends/#{frontend}/#{asset_type}/"
+        destination = "/public/#{asset_type}/active_scaffold/#{frontend}"
+        copy_files(source, destination, directory)
+      end
+    end
+
+    desc "Update Active Scaffold javascripts in public/javascripts/ from the plugin"
+    task :javascripts do
+      copy_asset_type('javascripts')
+    end
+
+    desc "Update Active Scaffold stylesheets in public/stylesheets/ from the plugin"
+    task :stylesheets do
+      copy_asset_type('stylesheets')
+    end
+
+    desc "Update Active Scaffold images in public/images/ from the plugin"
+    task :images do
+      copy_asset_type('images')
+    end
+  end
+end
Index: init.rb
===================================================================
--- init.rb        (revision 609)
+++ init.rb       (working copy)
@@ -6,4 +6,4 @@

 ##
 ## Run the install script, too, just to make sure
 ##
-require File.dirname(__FILE__) + '/install'
+## require File.dirname(__FILE__) + '/install'
as_asset_rake_tasks_patch.diff

Michael Latta

unread,
Aug 22, 2007, 7:49:21 PM8/22/07
to actives...@googlegroups.com
For AS I recommend the following ways to modify the default behavior:

1) Override controller/helper methods as documented (or undocumented at more risk).
2) Place your own stylesheet after the AS include on your page and define your own styles. You can either leave the classes alone and rely on your later sheet to win, or use the features of AS to customize the classes generated on the page.
3) Produce your own JS file for any patches to the javascript used by AS. You can patch methods and objects defined in AS this way.
4) Patch the AS modules and classes using regular Ruby monkey patching. If you replace a method there is some maintenance/risk, if you just alias the AS method and wrap it with your own similarly named method there is very little risk.

I have made some fairly deep changes this way and only had to replace 1 method in all of AS and its JS files.

Michael





<as_asset_rake_tasks_patch.diff>

rrwhite

unread,
Aug 22, 2007, 10:24:28 PM8/22/07
to ActiveScaffold : Ruby on Rails plugin
Michael wrote:
"2) Place your own stylesheet after the AS include on your page and
define your own styles. You can either leave the classes alone and
rely on your later sheet to win, or use the features of AS to
customize the classes generated on the page."

This is how I always do it and is the official AS sanctioned way as
well, though I don't know how well we document that.

Unfortunately, even if we slapped files named DO_NOT_MODIFY into each
of the AS asset folders and posted similarly scary messages at the top
of each asset file, I'm sure a lot of people would do exactly as
Stephen did. Therefore, I support can support this change especially
given that it parallels what Rails does on this matter.

Principle of least surprise rules the day.


On Aug 22, 4:49 pm, Michael Latta <lat...@mac.com> wrote:
> For AS I recommend the following ways to modify the default behavior:
>
> 1) Override controller/helper methods as documented (or undocumented
> at more risk).
> 2) Place your own stylesheet after the AS include on your page and
> define your own styles. You can either leave the classes alone and
> rely on your later sheet to win, or use the features of AS to
> customize the classes generated on the page.
> 3) Produce your own JS file for any patches to the javascript used by
> AS. You can patch methods and objects defined in AS this way.
> 4) Patch the AS modules and classes using regular Ruby monkey
> patching. If you replace a method there is some maintenance/risk, if
> you just alias the AS method and wrap it with your own similarly
> named method there is very little risk.
>
> I have made some fairly deep changes this way and only had to replace
> 1 method in all of AS and its JS files.
>
> Michael
>
> On Aug 22, 2007, at 3:54 PM, Stephen Bannasch wrote:
>
> > At 3:04 PM -0700 8/17/07, Lance Ivy wrote:
> >> But `./script/plugin update active_scaffold` doesn't call an
> >> update.rb file, so how would ActiveScaffold know that was
> >> happening? And what if someone isn't using ./script/plugin? What
> >> if they're using Piston? Or they use svn directly, or unpackage
> >> the zip distributable?
>

Stephen Bannasch

unread,
Aug 22, 2007, 11:09:49 PM8/22/07
to actives...@googlegroups.com
At 3:04 PM -0700 8/17/07, Lance Ivy wrote:
But `./script/plugin update active_scaffold` doesn't call an update.rb file, so how would ActiveScaffold know that was happening? And what if someone isn't using ./script/plugin? What if they're using Piston? Or they use svn directly, or unpackage the zip distributable?

On 8/17/07, Don.M...@gmail.com <Don.M...@gmail.com> wrote:

Only when a user runs
script/plugin update active_scaffold

would any updated javascripts and stylesheets
should be copied to the public directory.


That way it is under my control. That is when
any updates would occur anyway as far as changes to files.

On Aug 17, 4:33 pm, "Lance Ivy" < la...@cainlevy.net> wrote:
> Right, so what should happen when ActiveScaffold's javascript and
> stylesheets get updated?

The behavior of AS (I'm using trunk) where it copies the assets from the plugin to public/ every time the plugin is initialized is also a problem for me.  I was learning AS and busy changing the css files (to make it look the way I wanted it to) and was confused about why my changes kept disappearing. I ended up adding my own frontend dir into the plugin folder, doing my edits there and restarting the server to see them -- very annoying.

If I am updating plugins using Piston or svn I expect to have read the documentation and know if I need to run something if there are assets that might need updating.

This is what happens when I update rails and prototype or scriptaculous have been updated. I need to run this rake task:

  rake rails:update:javascripts

Which does this: "Update your javascripts from your current rails install".

So here's my patch which stops AS from copying the assets when it is initialized and adds these rake tasks. Patch is derived from code in install.rb and my changes are released as public domain.

Update Active Scaffold assets (javascripts/stylesheets/images) in  public/ from the plugin:

  rake active_scaffold:update

Update Active Scaffold images in public/images/ from the plugin:

  rake active_scaffold:update:images

Update Active Scaffold javascripts in public/javascripts/ from the plugin:

  rake active_scaffold:update:javascripts

Update Active Scaffold stylesheets in public/stylesheets/ from the plugin:

  rake active_scaffold:update:stylesheets

Index: tasks/active_scaffold.rake
===================================================================
--- tasks/active_scaffold.rake      (revision 0)
+++ tasks/active_scaffold.rake      (revision 0)
@@ -0,0 +1,42 @@
+namespace :active_scaffold do
+
+  desc "Update Active Scaffold assets (javascripts/stylesheets/images) in  public/ from the plugin"

+  task :update => [ "update:javascripts", "update:stylesheets", "update:images" ]
+
+  namespace :update do
+
+    def copy_files(source_path, destination_path, directory)
+      source, destination = File.join(directory, source_path), File.join(RAILS_ROOT, destination_path)
+      FileUtils.mkdir(destination) unless File.exist?(destination)
+      puts "Copied: #{Dir.glob(source+'/*.*').collect {|f| f.split(source+'/')[1]}.join(', ')} \n    to: #{destination}."

+      FileUtils.cp_r(Dir.glob(source+'/*.*'), destination)
+    end
+
+    def copy_asset_type(asset_type)
+      directory = File.join(File.dirname(__FILE__), '..')
+      available_frontends = Dir[File.join(directory, 'frontends', '*')].collect { |d| File.basename d }
+      path = "/public/#{asset_type}/active_scaffold"
+#      copy_files(path, path, directory)
+      available_frontends.each do |frontend|
+        source = "/frontends/#{frontend}/#{asset_type}/"
+        destination = "/public/#{asset_type}/active_scaffold/#{frontend}"
+        copy_files(source, destination, directory)
+      end
+    end
+
+    desc "Update Active Scaffold javascripts in public/javascripts/ from the plugin"
+    task :javascripts do
+      copy_asset_type('javascripts')
+    end
+
+    desc "Update Active Scaffold stylesheets in public/stylesheets/ from the plugin"

Lance Ivy

unread,
Aug 23, 2007, 1:12:16 AM8/23/07
to actives...@googlegroups.com
One of the original reasons for the automatic asset copy was so we wouldn't have to field as many questions from people who just hadn't run the update task yet. Not everyone expects that, and this plugin does attract developers with a wide range of experience and expectations. But the tradeoff has been that we instead field questions from people who've lost changes to their CSS customizations, or have other problems (practical or philosophical) with the approach.

Something else to consider is that even if you expect to have to run an update task ... should you? Before Rails I expected to do a lot of stuff that happens automatically now. So the real question is whether the automatic asset copy is progress? Maybe not. Hard to tell.

But ok, I'll go ahead and switch to the rake task approach here. Getting people to use it should just be a matter of mentioning it at every release point, and getting the word out to people who run trunk.

> > +      available_frontends = Dir[File.join (directory, 'frontends',

Stephen Bannasch

unread,
Aug 23, 2007, 10:26:21 AM8/23/07
to actives...@googlegroups.com
At 10:12 PM -0700 8/22/07, Lance Ivy wrote:
>Something else to consider is that even if you expect to have to run an update task ... should you? Before Rails I expected to do a lot of stuff that happens automatically now. So the real question is whether the automatic asset copy is progress? Maybe not. Hard to tell.
>
>But ok, I'll go ahead and switch to the rake task approach here. Getting people to use it should just be a matter of mentioning it at every release point, and getting the word out to people who run trunk.

Thanks Lance,

I also expect much to happen automatically with rails but I don't expect changes I make to files under public/ to be reverted. The immediacy of making a change and seeing the result when I refresh the browser is part of what I expect with rails. I didn't initially think of overriding the AS stylesheets with one of my own (didn't see this in the doc). After I got AS working in a simple model/controller the next thing I wanted to do was to make it look like it fit in with the rest of my app. The css was well documented and easy to change -- just the process of where this is best done wasn't clear.

I don't expect a generator to keep generating after I've run it once unless I run it again.

I also expect (well really just hope) that a plugin has a set of documented administrative or maintenance rake tasks if it needs them. I'll often look at these tasks as part of how I learn about the plugin and consider rake tasks in effect documentation.

Here's an idea:

1) Include a digest for each directory of assets (include this digest in the repository too).
2) When AS is installed and the assets are first copied to public/ the digests are copied too.
3) When AS starts up init.rb can compare the digests in the plugin and public directories and log a warning when they are different. The comparison is done on existing digests so the cost of calculation does not occur during the init process. In addition my concept is that the comparison is between what currently exists in the plugin dir and what was copied earlier to to public/. I am now assuming that calculating and saving a new digest always follows making changes in the assets in the plugin dir (normally only done by developers).
4) The rake tasks for updating the assets can calculate a digest for the exising assets in public/ and if this calculated digest is different that the cached digest in public/ the task can warn that local changes are about to be over-written and ask the user what to do.
5) Rake tasks can be added for calculating the digests for use by developers.
6) Version info could be used to make messages to AS users more informative.

fyi: how to calculate a digest for a collection of files:

require 'open-uri'
require 'digest/sha1'
file_names = Dir.glob('vendor/plugins/active_scaffold/frontends/default/stylesheets/*.css')
Digest::SHA1.hexdigest(file_names.collect {|f| open(f).read }.join)

=> "a360c4c666e717ec6c998f228af41bb6b851b66c"

Of course it's silly to use SHA1 here -- I should have used MD5 which takes much less computational effort.

Michael Latta

unread,
Aug 23, 2007, 11:38:27 AM8/23/07
to actives...@googlegroups.com
I really feel it is progress. And, that modifying assets produced by another project/team is really bad development practice that does not need to be supported. What happens when a new CSS sheet is added to AS that depends on things in the modified sheet, and then AS gets blamed for it not working because the developer that worked on it 6 months ago modified an asset. There are so many horror stories about bad CM practices that we as a community should educate about the reasons not to modify assets rather than catering to that practice.

Michael

steegi

unread,
Aug 27, 2007, 12:31:05 AM8/27/07
to ActiveScaffold : Ruby on Rails plugin
I am with Michael on this issue though I have ran into the problem
myself. It also took me a few times before I realized what was
happening and saw the problem with my sinful ways :).

I also feel that this feature is a step in the right direction for AS
and Rails both in terms of convenience as well as an incentive to use
good CSS practices and therefore shouldn't be changed. That being said
I am in favor of both better documentation with respect to the usage
of alternative CSSs and a provision to minimize overhead in
production.

Just my 2 cents.

Frank.

Lance Ivy

unread,
Aug 29, 2007, 2:12:19 PM8/29/07
to actives...@googlegroups.com
So yeah, I was all set to patch this in last week and then we heard from the pro-autocopy lobby. I'm going to leave it as-is, and add a little documentation. It seems like moving to rake tasks would be the sort of change for a major version update.

Lance Ivy

unread,
Aug 29, 2007, 2:47:53 PM8/29/07
to actives...@googlegroups.com
http://activescaffold.com/tutorials/faq#custom-css

Also adding a DO_NOT_EDIT warning file to public/stylesheets/active_scaffold and public/javascripts/active_scaffold, which refers to the FAQ item above.

bokmann

unread,
Sep 25, 2007, 1:43:54 PM9/25/07
to ActiveScaffold : Ruby on Rails plugin
I just came across this thread because this init/install issue caused
us a probem in production.

Our sysadmin had permissions on stuff locked down tightly, and the
user starting the server didn't have permission to write to the public
directory. Server wouldn't start, and he had a heck of a time
figuring it out.

This has to be a somewhat common problem with this plugin in
production environments.

When he told me that the plugin was trying to run the install script
at server start, I didn't believe him. In just seems conceptually
'impure' to have an init script run an install script for something
that is already installed.

give me a rake task: "as:restore" that can redo the copies. While I
agree it would be bad practice to modify those files, if they have
been copied under public (where I would add them to svn), it is
reasonable to consider them fair game in the public tree, and
unreasonable to assume you will have permission to write there at
startup. It is a *much worse* practice to have to go in and comment
out the install line in the init, which is what we might end up doing.

-db


On Aug 29, 2:47 pm, "Lance Ivy" <la...@cainlevy.net> wrote:
> http://activescaffold.com/tutorials/faq#custom-css
>
> Also adding a DO_NOT_EDIT warning file to public/stylesheets/active_scaffold
> and public/javascripts/active_scaffold, which refers to the FAQ item above.
>
> On 8/29/07, Lance Ivy <la...@cainlevy.net> wrote:
>
>
>
> > So yeah, I was all set to patch this in last week and then we heard from
> > the pro-autocopy lobby. I'm going to leave it as-is, and add a little
> > documentation. It seems like moving to rake tasks would be the sort of
> > change for a major version update.
>

Lance Ivy

unread,
Sep 25, 2007, 1:52:40 PM9/25/07
to actives...@googlegroups.com
Trunk addresses this problem by recovering in production mode. See http://activescaffold.googlecode.com/svn/trunk/init.rb.

And I don't think it's worse practice to comment a line out of init.rb than it is to edit the CSS files in /public. They're both plugin code. They both have the same rules for modification: at your own risk. If there were a better way to serve assets without copying them into /public or creating a dedicated asset controller (like Typo), we'd be all over it.
Reply all
Reply to author
Forward
0 new messages