If you dislike the way rails default scaffolds look, this code will allow you to make them look however you want. Our goal is to create a customized scaffold that will create views based on your own design. To do this, we''ll create a new generator component that extends the functionality of the original scaffold component. For purposes of this article, let''s create one that uses tables rather than tags to separate fields. We''ll call it table_scaffold. Thus, when were done, you''ll be able to generate a scaffold with your design by running: ruby script\generate table_scaffold SomeObject The first step is to create a skeleton for our scaffold component. To do this, we''ll create a folder under [RAILS_HOME]/lib/rails_generator/generators/components called table_scaffold/. Then, copy the templates/ folder from the original scaffold directory into the new one. Scaffold uses form.rhtml to generate the objects _form.rhtml page, so we can modify it to add in our base table tag. Here is what the new one looks like: <code> <%%= error_messages_for ''<%= singular_name %>'' %> <table> <%= template_for_inclusion %> </table> </code> Now for the tougher part. We need to create our own class to override the generation of the fields themselves. To do this we need to extend two classes, namely, ScaffoldSandbox and ScaffoldGenerator. To do this, first we create a file called table_scaffold_generator.rb in our table_scaffold folder. First we''ll add our version of the ScaffoldSandbox class, as it has the method that generates each field, default_input_block: require ''rails_generator/generators/components/scaffold/scaffold_generator'' class TableScaffoldingSandbox < ScaffoldingSandbox def default_input_block Proc.new { |record, column| <<-END_ROW <tr> <td> <label for="#{record}_#{column.name}">#{column.human_name}</label> </td> <td> #{input(record, column.name)}</b></p> </td> </tr> END_ROW } end # default_input_block end # class TableScaffoldingSandbox Now, we need to add our own Generator class and override it so that it uses our Sandbox. To do this we extend ScaffoldGenerator and re-implement the create_sandbox method. To do this, I simply copied the existing method and modified it: class TableScaffoldGenerator < ScaffoldGenerator def create_sandbox sandbox = TableScaffoldingSandbox.new sandbox.singular_name = singular_name begin sandbox.model_instance = model_instance sandbox.instance_variable_set("@#{singular_name}", sandbox.model_instance) rescue ActiveRecord::StatementInvalid => e logger.error "Before updating scaffolding from new DB schema, try creating a table for your model (#{class_name})" raise SystemExit end sandbox.suffix = suffix sandbox end # create_sandbox end #class TableScaffoldGenerator Thats it! There may be a better, or more elegant way to do this, but I haven''t found one. Let me know if you find this useful or have questions. This was orignally posted as an article here: http://www.tristanhavelick.com/item/6
This is great I''ve been able to change the table_scaffold behavior to only output the columns that I want, simply, by checking the contents of a variable. I want do the same with edit and new forms. How would I change the default_input_block so that it creates the ''_form.html'' with the folllowing code? I''ve tried several approaches, but I don''t understand what is happening enough to have much success: <code> <%= error_messages_for ''category'' %> <table> <!--[form:category]--> <% for column in Category.content_columns %> <% unless @hide_columns.include?(column.name <http://column.name>) %> <tr> <th> <%= column.human_name%> </th> <td> <%= input(Category, column.name <http://column.name>)%></p> </td> </tr> <% end %> <% end %> <!--[eoform:category]--> </table> </code> ----- -Larry _______________________________________________ Rails mailing list Rails-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org http://lists.rubyonrails.org/mailman/listinfo/rails
Here is the trick I use for customizing scaffolds (dynamic ones). I have created a scaffold_templates directory in my Rails application directory and copied the original scaffold templates in it. I have then included the following code in my environment: module ActionController module Scaffolding module ClassMethods def myscaffold(model_id, options = {}) scaffold(model_id, options) module_eval <<-"end_eval", __FILE__, __LINE__ private def scaffold_path(template_name) File.dirname(__FILE__) + "/../scaffold_templates/"+ template_name + ".rhtml" end end_eval end end end end Now, if I use myscaffold instead of scaffold in my controller, the resulting scaffold uses the templates in myapp/scaffold_templates instead of the original ones. Julien Faissolle Tristan Havelick wrote:>If you dislike the way rails default scaffolds look, this code willallow you to make them look however you want.
On 7/7/05, Faissolle, Julien <julien.faissolle-VXdhtT5mjnY@public.gmane.org> wrote:> > Here is the trick I use for customizing scaffolds (dynamic ones). I have > created a scaffold_templates directory in my Rails application directory > and copied the original scaffold templates in it. I have then included > the following code in my environment:Did you put this in ''environment.rb'' or someplace else? module ActionController> module Scaffolding > module ClassMethods > def myscaffold(model_id, options = {}) > scaffold(model_id, options) > module_eval <<-"end_eval", __FILE__, __LINE__ > private > def scaffold_path(template_name) > File.dirname(__FILE__) + "/../scaffold_templates/"+ > template_name + ".rhtml" > end > end_eval > end > end > end > end > > Now, if I use myscaffold instead of scaffold in my controller, the > resulting scaffold uses the templates in myapp/scaffold_templates > instead of the original ones. > > Julien Faissolle > > > Tristan Havelick wrote: > > >If you dislike the way rails default scaffolds look, this code will > allow you to make them look however you want. > _______________________________________________ > Rails mailing list > Rails-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org > http://lists.rubyonrails.org/mailman/listinfo/rails >_______________________________________________ Rails mailing list Rails-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org http://lists.rubyonrails.org/mailman/listinfo/rails
On 7/7/05, Faissolle, Julien <julien.faissolle-VXdhtT5mjnY@public.gmane.org> wrote: Here is the trick I use for customizing scaffolds (dynamic ones). I have created a scaffold_templates directory in my Rails application directory and copied the original scaffold templates in it. I have then included the following code in my environment: Did you put this in ''environment.rb'' or someplace else? I have put it in a file myscaffold.rb in the lib directory under my rails application directory. I just ''require'' it in environment.rb. module ActionController module Scaffolding module ClassMethods def myscaffold(model_id, options = {}) scaffold(model_id, options) module_eval <<-"end_eval", __FILE__, __LINE__ private def scaffold_path(template_name) File.dirname (__FILE__) + "/../scaffold_templates/"+ template_name + ".rhtml" end end_eval end end end end Now, if I use myscaffold instead of scaffold in my controller, the resulting scaffold uses the templates in myapp/scaffold_templates instead of the original ones. Julien Faissolle Tristan Havelick wrote: >If you dislike the way rails default scaffolds look, this code will allow you to make them look however you want. _______________________________________________ Rails mailing list Rails-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org http://lists.rubyonrails.org/mailman/listinfo/rails _______________________________________________ Rails mailing list Rails-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org http://lists.rubyonrails.org/mailman/listinfo/rails