Ruby on Rails Dynamic Models - ruby-on-rails

I'm working on an application where the end user defines what columns a database table should have based off column names in an Excel spreadsheet that gets uploaded or just by manually defining them before uploading the spreadsheet.
Is this something that AR and MySQL could handle or am I better off using mongodb or couchdb?
In the traditional way, I would basically need a new table each time a user uploaded a document. Am I correct in thinking that with mongodb or couchdb, I would just be defining the document instead of a table?
Thanks!

SQL, in general, has a few methods for handling such dynamic column assignments. MongoDB is definitely a much easier paradigm under which to store this data.
The big limitation here will be "what do you do when the data is in the system?". MongoDB has a built-in map-reduce, but this is obviously completely different from set-based SQL.
So to get more help, you'll probably want to detail what happens once the data is in.

You should checkout PostgreSQL hstore. It stores a key-value field that can be indexed. There is support for ActiveRecord here https://github.com/engageis/activerecord-postgres-hstore, which will allow you to just save a Ruby hash on that field.

Related

Where to place sql queries in rails?

I have started a rails project on top of a legacy database. Standard practices required to use an ORM, like assigning ID field to each table, haven't been followed. So, I will not be creating all the models matching all the table. I need to run queries joining multiple tables using numerous conditions. I will mostly be using Model.find_by_sql or Model.connection.select_all methods. Where should I put these queries? Should I stash these in one of the models I have created that is involved in the query?
What's the standard practice for such a situation?
As much as possible, you still want to insulate the rest of your application from the details of the database by putting your queries and whatnot into the model layer. So yes, "stashing" in the right model object relevant to what you're trying to do seems like the right thing.
Are you allowed to change the schema of the database? If so, you may want to use migrations to slowly make your database look more like a standard ActiveRecord backing store.
You may also want to look into alternatives to ActiveRecord such as Sequel.
It is good idea to place the sql queries under sql folder under db. You need to create the sql folder.

What's the best database structure for a Rails app like Wufoo?

I am not intending to rebuild Wufoo on Rails but want to create an app along those lines.
Any advice on the best app/database structure for this?
A postgres hstore strategy would be preferable to serializing. And yes, there's a gem for activerecord hstore support.
To quote their readme:
You need dynamic columns in your tables. What do you do?
Create lots of tables to handle it. Nice, now you’ll need more models
and lots of additional sqls. Insertion and selection will be slow as
hell.
Use a noSQL database just for this issue. Good luck.
Create a serialized column. Nice, insertion will be fine, and reading data from
a record too. But, what if you have a condition in your select that
includes serialized data? Yeah, regular expressions.

How to store user generated content in Rails app

I want to create an website where users can create their own teaching resources, e.g. blocks of text with embedded images etc.
How should I store this in a database in rails? I've heard mongoDB is good for storing documents but I was planning on using postgresql for the user database etc. and have read that generally you shouldn't mix different types of db
I'm sure this is an obvious question but I couldn't find an answer anywhere...
Thanks,
Graham
There are several things you could do.
1. Use PostgreSQL for both the Users table and the TeachingResources table. You could simply use a content column of type text to save all the data.
2. Use PostgreSQL but use the HStore functionality to basically store a hash of objects of your choosing, this gives you more flexibility. Rails 4 will support this by default, but there is also a gem you can use.
3. Use a combination of PostgreSQL and MongoDB (or any other NoSQL solution) in your app. I don't see this as a bad solution, but it does put you outside of the "new user constraints" in Rails, so this might not be the best route to start with
4. Go NoSQL all the way. There is no reason you shouldn't be able to use MongoDB for your User model. However, you are right that this type of datastorage can not give full ACID guarantees, so be careful with product planning and know it's vulnerabilities (but also its strengths).

How do you add sqlite3 file to a ruby on rails populated database?

I have a Ruby on Rails application with a database that is populated with programs. I also have a sqlite3 database that is almost exactly like the database in the RoR app (without created, updated). I want to import the sqlite3 database into the Rails app (not with the database.yml file, combining the two databases) and after much google searching, I can't figure out how and where to do this. What file where I'd do this in and what would be the best way to do it?
The low-tech approach is to dump your SQLite database into something you can import into your other database. MySQL has LOAD DATA INFILE that's quite flexible and can even read CSV files if configured correctly, so that could be a simple method.
Generally I find it's best to import your external tables as-is but convert the names so they can be identified as being non-native. For instance, prefix all of them with _import to make it clear they're not part of your regular schema. You can then migrate from those tables to your native ones using a series of statements that perform the remapping:
INSERT INTO foo (x,y) SELECT (x,y) FROM _import_foo
That makes it easy to account for missing columns or slight differences in names. You can also perform conversion on particular columns if so required.
As always, be sure you have a snapshot of your database before you start this operation as is is usually tricky to un-merge things.
The other approach is to create two database connections simultaneously and shuttle data between the two using SELECT on one side and INSERT INTO on the other.

How to create a user customizable database (like Zoho creator) in Rails?

I'm learning Rails, and the target of my experiments is to realize something similar to Zoho Creator, Flexlist or Mytaskhelper, i.e. an app where the user can create his own database schema and views. What's the best strategy to pursue this?
I saw something about the Entity-Attribute-Value (EAV) but I'm not sure whether it's the best strategy or if there is some support in Rails for it.
If there was any tutorial in Rails about a similar project it would be great.
Probably it's not the easiest star for learning a new language and framework, but it would be something I really plan to do since a long time.
Your best bet will be MongoDB. It is easy to learn (because the query language is JavaScript) and it provides a schema-less data store. I would create a document for each form that defines the structure of the form. Then, whenever a user submits the data, you can put the data into a generic structure and store it in a collection based on the name of the form. In MongoDB collections are like tables, but you can create them on the fly. You can also create indexes on the fly to speed searches.
The problem you are trying to solve is one of the primary use cases for document oriented databases which MongoDB is. There are several other document oriented databases out there, but in my opinion MongoDB has the best API at the moment.
Give the MongoDB Ruby tutorial a read and I am sure you will want to give it a try.
Do NOT use a relational database to do this. Creating tables on the fly will be miserable and is a security hazard, not just for your system, but for the data of your users as well. You can avoid creating tables on the fly by creating a complex schema that tracks the form structures and each field type would require its own table. Rails makes this less painful with polymorphic associations, but it definitely is not pretty.
I think it's not exactly what you want, but this http://github.com/LeonB/has_magic_columns_fork but apparently this does something similar and you may get some idea to get started.
Using a document store like mongodb or couchdb would be the best way forward, as they are schema-less.
It should be possible to generate database tables by sending DDL-statements directly to the server or by dynamical generating a migration. Then you can generate the corresponding ActiveRecord models using Class.new(ActiveRecord::Base) do ... end. In principle this should work, but it has to be done with some care. But this definitely no job for a beginner.
A second solution could be to use MongoMapper and MongoDB. My idea is to use a collection to store the rows of your table and since MongoDB is schema less you can simply add attributes.
Using EntryAttributeValue allows you to store any schema data in a set amount of tables, however the performance implications and maintenance issues this creates may very well not be worth it.
Alternately you could store your data in XML and generate an XML schema to validate against.
All "generic" solutions will have issues with foreign keys or other constraints, uless you do all of that validation in memory before storage.

Resources