Friday, April 25, 2008

DRY Up Your Views With Layouts For Your Partials

I got comments on my previous post, DRY up your views with nested partials, letting me know that there is a better way. So here is the same thing, done the proper way:


First, I've got this cool set of divs that gives me a nice looking window I will be reusing:


 
<div id="window-top"></div>
<div id="window">
<%= render :partial => 'mypartial' %>
</div>
<div id="window-bottom"></div>

<div id="window-top"></div>
<div id="window">
<%= render :partial => 'myotherpartial' %>
</div>
<div id="window-bottom"></div>

The goal here is to be able to re-use the code for the window multiple times. First, lets create a partial called '_lorem.html.erb':



<p>"Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do
eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim
veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse
cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat
non proident, sunt in culpa qui officia deserunt mollit anim id est
laborum." </p>

And another called '_blah.html.erb':



<p>blah blah blah blah blah blah blah blah blah blah blah blah blah
blah blah blah blah blah blah blah blah blah blah blah blah blah blah blah
blah blah blah blah blah blah blah blah blah blah blah blah blah blah blah
blah blah blah blah blah blah blah blah blah blah blah blah blah blah blah
blah blah blah </p>


Alright! Now, make one last partial, which will be used for the layout, called '_window.html.erb'. Note that it needs to be created in the same directory as the other partials. This is where you put the code for the cool window you just made.



<div id="window-container">
<div id="window-top-left"></div><div id="window-top">Window Title</div>
<div id="window-top-right"></div>
<div id="window">
<%= yield %>
</div>
<div id="window-bottom-left"></div><div id="window-bottom">
</div><div id="window-bottom-right"></div>
</div>

And now, when you want to render a partial that is inside your window, all you need to do is set the layout to window:



<h1>Test of nested partials</h1>

<%= render :partial => 'blah', :layout => 'window' %>

<%= render :partial => 'lorem', :layout => 'window' %>


And thats it! Enjoy DRYing up your views. Later

-Ralph



EDIT: if you use :layout => 'layouts/window', you can put '_window.html.erb' in /views/application and reuse it throughout the site.

Wednesday, April 16, 2008

DRY up your views with nested partials

NOTE: I got a couple of comments letting me know that the proper way to do this is to use a layout with your partial. Please see this post for instructions. Since making this post, I've been told the partial nesting is generally a bad idea, so use at your own risk.




Got a good one for you today that should help clean up your views and DRY things out. How many times, when building a website, do you use the same code over and over again to build this cool looking window that is re-used over and over?


 
<div id="window-top"></div>
<div id="window">
<%= render :partial => 'mypartial' %>
</div>
<div id="window-bottom"></div>

<div id="window-top"></div>
<div id="window">
<%= render :partial => 'myotherpartial' %>
</div>
<div id="window-bottom"></div>

Well, you can use nested partials to achieve the same effect and re-use your window code. First, lets create a partial called '_lorem.html.erb':



<p>"Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do
eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim
veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse
cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat
non proident, sunt in culpa qui officia deserunt mollit anim id est
laborum." </p>

And another called '_blah.html.erb':



<p>blah blah blah blah blah blah blah blah blah blah blah blah blah
blah blah blah blah blah blah blah blah blah blah blah blah blah blah blah
blah blah blah blah blah blah blah blah blah blah blah blah blah blah blah
blah blah blah blah blah blah blah blah blah blah blah blah blah blah blah
blah blah blah </p>


Alright! Now, make one last partial, '_window.html.erb'. This is where you put the code for the cool window you just made.
Inside of it, you want to render a partial, and pass in the variable 'name':



<div id="window-container">
<div id="window-top-left"></div><div id="window-top">Window Title</div>
<div id="window-top-right"></div>
<div id="window">
<%= render :partial => name %>
</div>
<div id="window-bottom-left"></div><div id="window-bottom">
</div><div id="window-bottom-right"></div>
</div>

And now, when you want to render a partial that is inside your window, all you need to do is render the 'window' partial, and as a local
variable named 'name', pass in the name of the partial you want rendered inside of it:



<h1>Test of nested partials</h1>

<%= render :partial => 'window', :locals => {:name => 'lorem' } %>

<%= render :partial => 'window', :locals => {:name => 'blah' } %>


And thats it! Enjoy DRYing up your views with nested partials. Later

-Ralph

Wednesday, April 9, 2008

ActiveScaffold - Helpers for columns with same name overwrite each other - FIX

Really quick one today. I was working on my ActiveScaffold project, and came across the following problem:
My Events table has a column called schools, and so does my Schools table. For the Events, I needed a dropdown box listing all schools...while for Schools, I needed a text box to show up to type in the name of the school. Since textboxes are the default for activescaffold, I shouldn't need to do anything with schools in it, however, when I wrote a form override for Events in event_helper.rb to give it a dropdown box...the dropdown showed up in Schools also. So first, I tried doing a form override in the school_helper.rb. No luck, the event helper method has the same name, and overrides whatever method I put in school with the same name. So to fix it, I removed my helper methods from the event and school helpers. In application_helper.rb, I made a function with the same name as the form override function I had been trying to use, and then used an if to determine which model the helper was being called from. Here is the code:


# Methods added to this helper will be available to all templates in the application.
module ApplicationHelper

#hack to make activescaffold form overrides work when 2 models have a field that is the same name
def school_form_column(record, input_name)
if record.class.name == "Event"
select_tag input_name, options_for_select(aschools, selected = record.school)
else #record.class.name =="School"
text_field :record, :school, :name => input_name
end
end

private
#used in case of Event
def aschools
@schools = School.find(:all, :order => 'school')
@schooloptions = Hash.new
for school in @schools
@schooloptions[school.school] = school.abbrv
end
@schooloptions = @schooloptions.sort.each { |e| puts "#{e[0]} => #{e[1]}" }

end

end



Me: 2
ActiveScaffold: 0

Done.

Wednesday, April 2, 2008

Rails 2.0 Links

Decided to make a post with links to all the good resources I have come across so far. I'll be putting a permanent link to it on the sidebar. Feel free to leave a comment if you have any links you would like me to add.


RubyPlus.org - Lots of good screencasts; Restful Authentication, AWDR's Depot app for Rails 2.0


Rails Envy - They have a great ActiveRecord intro video here, among other things


Railscasts - Should need no introduction :)


Planet Ruby on Rails - Has feeds from many different Rails blogs all in one convenient place


InstantRails - For you Windows users, this program is a quick way to get up and going with Rails


DanielFischer.comTutorial for using Gmail as a mail server for a Rails project.


Jonathan s ng - ActionMailer Tutorial


Render Examples - Great render examples, helps when needing to render things with AJAX


Absolute Moron's Guide to Forms in Rails - Great form tutorial



Will be adding many more links in the days to come, this is just a preliminary list. Also, I would like to get some links for setting up Rails for development on several OS's(Linux flavors, MAC, ...), so if you have any please leave a comment.


Later.

-Ralph