views:

54

answers:

2

I am developing a website in Ruby on Rails, MySQL, and Javascript.

The website is modular, meaning that a user can customize their homepage and drag and drop one module to another area where it will live. there are three columns where the module can be dropped. (Think iGoogle or Netvibes)

What is the best way to store this data, so that when the user returns their homepage can be reconstructed quickly?

I've considered doing it in a way where each module get's an ID that corresponds to the user, it's row and it's positiong in that row. (So something like.. user|column|row, would equal 1204|3|27, meaning that for user #1204 this module would be in column #3 and 27 spaces from the top.

Then when the user returns, just loop through, adding 1 to each until it reaches the end of the column and start again at the other one until all 3 columns are populated.

I feel like this would be very slow though, and there must be a better way to do it.

Any suggestions? Mostly looking for Database structure, but if you have some Rails code that would corrilate to this I wouldn't mind seein git.

+1  A: 

I think the best is to keep your data in a single text field

For example 1204|3|27 should be in a text field ... with a good index per user id you should get the configuration very very fast. After that you just need to "explode" your configuration for "|" .

Regards

Sacx
A: 

I say model it very straightforwardly:

class ModuleInstallation < AR::Base
  belongs_to :user
  belongs_to :module
  validates_presence_of :column
  validates_presence_of :row
end

class User < AR::Base
  has_many :module_installations, :order => :column
  has_many :modules, :through => :module_installations
end

Then let your controller handle any more sorting, something like this (untested, but look through it and the documentation for the methods I'm using to get the concepts):

@columns = current_user.module_installations.group_by(&:column)
@columns.each { |column, modules| modules.sort! { |x,y| x.row <=> y.row } }

Then your view is relatively simple:

<% @columns.each do |column, modules| %>
  <div class="column-<%= column %>">
    <% modules.each do |module| %>
      <div class="module">
        <%= module.to_html %>
      </div>
    <% end %>
  </div>
<% end %>
Ian Terrell