Rails directory database structure - ruby-on-rails

I'm building a "small" personal web app in Ruby on Rails. I've set it up so that I'm using a MySQL database.
The idea is that I'm gonna store and navigate many kinds of data (notes, bookmarks, movie and appliction ratings) with this app.
I want to index/categorise this data in a pseudo-directory structure.
(The directory structure exists only in the database - not in actual directories)
E.g. a bookmark could be stored in Root -> Bookmark -> Funny -> Keyboard cat
Now I've seen this question but I don't now whether that solution is the best way to do it in a rails app.
A solution similar to the one in the question I linked to above was also what I had in mind. But one could also add an extra table having the relations between folders and their content.
The question is how do I structure my models and my database? (The "right" way)
Update: (#Dave and other taggers)
Yes, I've thought about tags. And at first I was actually going to ask a much larger question but I was unable to do so in a concise way. The deal is that it's also going to be possible to tag items. And in reality the directories ARE tags - you could say I want to have two ways of organising things - 'structured' tags (directories) and 'free' tags (your old regular tags). But that's a whole different story...
For now I just wanna see the "right" way of doing the rails model and the database structure for the directory problem.

It sounds like you'd want a series of one-to-many relationships, if it's truly mimicking a directory structure. E.g. pictures (like 'keyboard cat') can belong to only one category (like 'funny'), while each category can have many pictures.
However, you may want to rethink the directory structure & opt for something more flexible, like tags. Because if 'keyboard cat' could belong to more than just 'Funny', it would break the one-to-many relationships that defines a standard directory-like structure.

Related

ActiveRecord: How to mark as duplicate and merge?

I have several external feeds providing data to my application's database. The problem is that sometimes what should be the instance is named slightly differently in two different feeds.
For example, one feed might use the name Tom Cruise while another might use Thomas Cruise. It's not a big deal, but the issue is that both end up with different associations depending on what feed they come from.
My question is: is there a way (or a gem) to be able to mark one as a duplicate of the other and merge all its associations to the canonical one?

How to store and manage singular data in Rails?

I'm developing a site with Ruby on Rails. I have data on layout that doesn't repeat more then once. And I need to enable content-menegers to change it easily. I could create a model or several models for them and let content-managers edit it in RailsAdmin. But I doubt I should use models that way because entities of such models will be ment to exist in singular number. I mean there aren't multple site names, logos, backgrounds, welcoming texts, etc. But I want to enable them to be edited in a web-interface or equally comfortable not worrying about the cache and not looking at code and serfing through complicated directories structure.
What is the right way to do that?

Deciding between using an array attribute or a nested model

Possibly a fairly basic question, but bear with me.
I'm building a page which has a number of pieces of modular content, represented by a ContentBlock model. Each ContentBlock has at least one link, each of which has a couple of different attributes. My initial approach was to just add these links as an array to the model, as there didn't seem to be any real need to store them separately in the database, and they don't have any logic of their own. Now that I'm looking at building a form for creating/editing a ContentBlock though, it seems like it would be much easier to build if there was a separate, nested model for the links.
I'm strongly considering converting to using a model, but my gut feeling is that it's kind of "wrong" to store something like as relatively trivial as the links are in the DB. Given I am still getting used to working with Rails, is this feeling misplaced? Should I just create models for anything and everything? Or should I be looking for some sort of minimum criteria before I do?
It is definitely easier to create forms for nested models. Since your links have attributes, I'd suggest making a model. I tend to err on the side of making models for concepts that can't easily fit into fields. If you're worried about query performance, you can always do eager loading.
I think depends on how much data you plan on managing, what you want to do against that data, what that data represents, etc...
One project we had was to build something that allowed creation of recipes for a group of restaurants. Recipe (some text, like instructions, etc...) -> Ingredient, we went with an array, as these were all single lined text and there would never be more than several hand fulls. Also, the ingredients had no further dependencies. The Recipes would only be rendered out to html and there would be no searching against them (not against the db at least).
Another project required building a Page, very similar to yours, but each "component" of the page did different things and some where linked to other objects in the app, like Videos and other assets, templates, etc... We had seen people do this type of stuff entire through a wysiwyg or through some JS way and saved the entire payload/structure in the DB. We found both to be extremely messy.
And one concern that came up was what happened if an asset/associated object was mistakenly or purposely deleted but lived throughout many pages. Using models allowed to ensure that if something got removed, it got removed within all it's linked associations (though this posed problems of it's own, but more regarding the page making sense when displayed more than anything else).
Also, our Page had the potential of becoming extremely large with different types of components with different looks and inter-activities, that this really was the only way we could properly manage it.
So I would look at your requirements and plan accordingly, context matters. And if you have to change it (which happens, a lot) then you'll change it.

Web-based form-builder for users in Ruby/Rails

First time posting in Stack Overflow, hope I'm doing this right.
I'm writing an app with Ruby on Rails right now. Without disclosing too much, the premise is that we have organizations and normal users. Organizations have events, which require users to answer a questionnaire before participating.
I'm pretty sure about these models / relationships that I will be using (this isn't really that important/pertinent to my question i think, but just wanted to give background):
organization (one to many) events
event (one to one) quesitonnaire)
questionnaire (one to many) users
(specific) response (one to one) user
The part I have a question about is how to implement the questionnaire. I want to give the ability to Organizations to essentially write / build their own forms. I'd like to stay away from them using code if that's possible (ie any DSL and whatnot).
I suppose the easiest way to do this is to give them a set number of text-area responses, so that I can consistently store the data and don't have to hassle around with how to configure storing this data (for example, maybe each event can only have exactly 5 responses to be filled in by textfield response by the user).
My ideal would be for the organization to be able to dynamically generate the forms on their own - maybe one questionnaire will have 1 text input, followed by 3 multiple choices, and maybe 2 short answers at the end; another one may have 5 multiple choices, and 1 short answer; yet another questionnaire might only have 1 text input...you get the idea.
So I see two parts of this problem - the first is the user interface for the organization to create the questionnaire. i'm imagining this wouldn't be terribly hard - ask them how many of each response type (MC, short answer) they would like to put into the form, give them the ability to rearrange them, etc.
The second part of the problem (what I'm more concenred about) is how to store/access this data. I'm guessing there's no dynamic-attribute sort of deal in ruby - storing some field with an unspecified number of parts and whatnot. i suppose i could make them all individual models (ie a question_response model, with :question, :response_type, :response, etc), but I'm fairly certain that's probably inefficient.
My initial guess is probably to serialize the data / use json; I worked briefly with Drupal 6 and this seems to be the way they did it. I was wondering if anyone else had any experience / suggestions though? I'm pretty new to Ruby so I was wondering if there's a gem out there or something that would help with what I'm trying to do.
Thanks!
You might want to look at the Surveyor gem
http://vimeo.com/7051279
*slightly old how-to video
https://github.com/breakpointer/surveyor
Surveyor does come with it's own DSL which is relatively easy to use (although can be abit restrictive at times). The data is saved as a set of question - answer values, so there is no actual specific model (beyond Surveys -> Questions (question_groups) -> Answers).
Originally I did look at having people submit their own Surveyor DSL specs - which would then be used to generate the actual survey via a Rake command.
I think if you need to build a dynamic model (and save the data) it is possible, although I am not not sure if you'll be able to get the Rake tasks to run to build the actual tables in a dynamic way due to permission restrictions.
Have a look at http://ruby-metaprogramming.rubylearning.com/ and Metaprogramming Ruby: Program Like the Ruby Pros by Paolo Perrotta, for some starters.

Considering a new Rails app with existing data (not a db, actual data) -- what is the best way to proceed?

I have been tasked with developing a new retail e-commerce storefront for my current job, and I am considering tackling it with RoR to A) Build a "real" project with my limited Rails knowledge, and B) Give management quick turnaround and feedback (they are wanting to get this done ASAP and their deadlines are rather unrealistic - I'm talking a couple of weeks to go from nothing to working model so they can start to market it with SEO/SEM and, I kid you not, "video blogging" because my boss heard that's the future).
We do have a database structure in place but it's absolutely terrible and was thrown together without rhyme nor reason, so I'm going to largely ignore it and create a new database from scratch; however, I have existing data that I need to load into the application (like I said, it's an e-commerce app and we have the product data). I need to massage this data into a usable format because our supplier provides it to us with cryptic, abbreviated column names and it's highly denormalized, especially in the categories (I've posted a question regarding it before - basically the categories table has six fields, one for each category/subcategory, with some of them being blank if that category doesn't apply).
There are two main issues that are giving me second thoughts:
As I said the data needs to be put into a "proper" database schema; I can't just load it as-is. I have some thoughts as to a good data model for it, but my analysis is not completed yet. There would end up being a large amount of joins tables to link various things together (e.g. products_categories, products_attributes, products_prices) etc and these tables would link products not via an ID but by their SKU (see below).
Everything already has an ID that's generated for it, but anything new I add needs to have one autogenerated; I doubt this will be a problem with any mature RDBMS, but I know Rails likes to generate IDs itself. Also, almost all of the product-related tables are linked by SKUs (and in the data provided by the supplier are actually a composite key consisting of the prefix and stock number, which combined make up the full SKU), not by IDs and I'm not sure if this will be a performance issue (of course, I could always manually create indexes on these columns to speed it up). It does mean that I'll need to break away from the Rails conventions, however.
In short, I think that Rails might be a good choice as far as time-to-market and ease-of-development, but having to work with the existing data content might turn into a pain because the application will need to be developed around that, instead of the "traditional" Rails app, and that factor is giving me major doubts about using Rails. There are also some other issues (having to set up a Linux server, and the fact that the area I live in has very few Rails developers so if I left the company I'd basically be holding them hostage as far as updates/modifications). I'm really unsure as to the best path to proceed.
I would develop the app as if you didn't have the data. Use the ORM and make your database the best it can be, but of course keep in mind what data you have to populate it with (eg: don't make crazy new constraints for things that will leave you going through old data record by record).
When you're done and tested, write an import script that pulls your real data onto your new database.
It's not that different from the conventional design/development model... Apart from you can do your data-input in a semi-automated fashion.
I was in the same situation not too long ago — a crappy PHP app that held ten years worth of all company data.
What I did was simply create a Migration model and added methods to import each resource.
class Migration
def migration_all
self.jobs
end
def self.jobs
...
end
end
The cool thing about this is that you can arrange which order resources are imported as one will likely reference another. I also added methods that directly modified the db schema. One nice trick if you have to keep an existing primary key is to create a field named 'legacy_id', copy over your existing primary key, and when you're done, simply remove the 'id' field, rename the 'legacy_id' field to 'id', then add the primary_key constraint on the new 'id' field.
Don't use the SKU as the unique key for each product - use the standard Rails incremented id.
SKU could change as it may be misentered, etc and that would make it a nightmare to change all of the references from other tables. Put your current id in a sku column, index it and update the references in your other tables to the Rails ids.
You'd be able to do Product.find_by_sku(params[:sku]) in your controllers, set up a /products/:sku route, etc. I don't see what you'd gain (other than a headache) by using your non generated ids as the database primary keys.
I'd also suggest running your old data through your app's validations to make sure you are not loading up a bunch of inconsistencies and erros. It will help your app run smoothly and highlight existing data errors at a point where you can fix them.
Don't assume the existing data is valid just because it is already there.

Resources