1

As a newb, I decided to build a "home inventory" application. I am now stuck on how to programmatically select a layout based on what type of item it is when viewing it in a browser.

According to my planning, so far I should have created a few models to represent types of items I can find in my home: Furniture, Electronics and Books.

class Book < ActiveRecord::Base
end

class Furniture < ActiveRecord::Base
end

class Electronic < ActiveRecord::Base
end

Now the Books model has things like isbn, pages, address, and category. Furniture model has things like color, price, address, and category. Electronics has things like name, voltage, address, and category.

Here is where I got confused. I know the property address is going to be the same for all of them. I also know that, I will need to create multiple "layouts" for 3 different types of items to show the different properties of said items with appropriate graphics and stylesheets.

But how will I go about deciding which category the item is so I can determine which layout to render.

According to me, this is how I will do it:

class DisplayController < ApplicationController
def display    
  @item = Params[:item]
    if @item.category  = "electronics"
   render :layout => 'electronics'
  end
end

In my routes.rb

map.display ':item', :controller => 'display', :action => 'display'

I only seem to have one concern with this, I probably will add a lot of categories later on and think there should be a more DRY-esque way of dealing, rather than hardcoding them.

I understand that I need to add into my layout html tags to display relevant information for that particular category.

----Questions----

  1. Is this the right way to approach this type of problem.
  2. Will this approach be compatible when I decide to add a gem like thinking_sphinx to run search.
  3. What issues do you see with my approach and how can I make it better.
  4. I was reading something about "Polymorphic Assoc", does that apply in this case, since category exist for all items?

Also, I was trying to get a routes to render a URL like "http://localhost/living-room-tv"

BriteLite
  • 55
  • 6

2 Answers2

1
  1. Probably this is the right way if you have 2-3 categories. If your system is going to grow, you'll surely want to make the implementation more flexible.

  2. Not sure what issues you expect with search. My best bet is that on the search results page you'll have items of different kinds, so you'll just need different partials to render them.

  3. As I said, adding support for different categories can be tedious with your current approach. I can suggest two things (not necessarily mutually exclusive):

    • use a convention for associating category name with a layout (e.g. category 'electronics' is rendered via electronics layout). This way you'll be able to just render :layout => @item.category, and this code is adding-new-categories-proof
    • as your system will grow and enhance, you might find it necessary to introduce a whole new model for your categories. Think of it now, maybe you'll want to do this right now.
  4. Polymorphic associations are a different thing. There should be two models for those, you currently have only one. See the Rails Guides, 2.9.

By the way, I'm not sure why you need the whole layout to differ for categories. If the overall look of your site is consistent, then it's probably more suitable to just have different partials for items of different categories.

Regarding the urls, this question has been brought up numerous times (here, and there).

Community
  • 1
  • 1
alex.zherdev
  • 23,914
  • 8
  • 62
  • 56
  • For all that I read about Partials, that is something that totally slipped my mind. Partials for the view section, and a Categories model, that I assume I will have to do as a has_one :category and then go from there. I'll try that in the meanwhile, and I'll ask for further help if need be. Thank you neutrino! – BriteLite Jun 15 '10 at 15:15
1

If I understand you correctly, what you want is not different layouts. What you want is different templates.

Layout means the general structure of the whole page, and it is usually common for the entire project, or maybe you'll have 2-3 layouts per project. (site wide layout, admin layout, and some other specific layout).

What you mention is that you want a different template to show the different attributes of books, furniture, and electronics.

Create a view file app/views/display/furniture.html.erb and another for books and electronics, and render it using render :template => 'furniture' instead of render :layout.

Now if there are common pieces of information among the different categories, what you should do is create a partial that only contains the common part. For instance, create a partial app/views/shared/address.html.erb, and inside your furniture.html.erb you would do render :partial => '/shared/address', :locals => {:address => @item.address}.

This will help you to keep the view logic as dry as possible, while providing you with flexibility to create custom templates for every category.

Faisal
  • 19,358
  • 4
  • 30
  • 33
  • Yes sir. That is indeed what I had in mind . I understand what I need to do now. I hope you don't mind if I ask for help in case I get stuck again. Until then, I'll try to implement it the 'template' way. Thanks again! – BriteLite Jun 15 '10 at 15:13
  • that's what stack overflow is for.. feel free to ask – Faisal Jun 15 '10 at 19:21