aborted
aborted

Reputation: 4541

Generate a Rails model from within code (invoke generator from a controller)

I have a particular need to be able to invoke a Rails command from within code (ie when some action occurs). I need a model to be created with specific fields (which will be determined by a form) and run the created migration in the end.

So this form I have would create all the fields, which then would result with the creation of a model with its certain fields (table and columns)

So, is there a way to invoke rails generate model NAME [field[:type][:index] field[:type] and bundle exec rake db:migrate from within a controller/ruby code?

Upvotes: 1

Views: 277

Answers (1)

Erin Call
Erin Call

Reputation: 1784

Rather than having one table per category, here's a more relational-database-y approach:

create table category (
    id serial primary key,
    name text not null
);

create table attribute (
    id serial primary key,
    name text not null
);

create table item (
    id serial primary key,
    category_id integer not null references category (id),
    description text
);

create table category_attribute (
    attribute_id integer not null references attribute (id),
    category_id integer not null references category (id)
);

create table item_attribute (
    attribute_id integer not null references (attribute.id),
    item_id integer not null references item (id),
    value text
);

When you create a category, you store its name (and any other one-to-one attributes) in the category table. You make sure the attribute table has an entry for every attribute the category has, and then use the category_attribute table to link those attributes to that category.

When you add a new member of a category, you use the item table to store the main things about the item and the item_attribute table to store the values of each of its attributes. So with the cars and pets approach you mentioned, your database might look like

category
 id | name
----+------
  1 | car
  2 | pet

attribute
 id |    name
----+------------
  1 | make
  2 | breed
  3 | model_year
  4 | name

category_attribute
 attribute_id | category_id
--------------+-------------
            1 |           1
            2 |           2
            3 |           1
            4 |           2

item
 id | category_id |  description
----+-------------+----------------
  1 |           1 | Hyundai Accent
  2 |           2 | Fuzzy kitty

item_attribute
 attribute_id | item_id |  value
--------------+---------+---------
            1 |       1 | Hyundai
            3 |       1 | 2007
            2 |       2 | DSH
            4 |       2 | Sam

This approach can feel pretty non-obvious, because it doesn't match the "one object with many attributes" style you use with Rails models. This is how relational databases work, however. I believe there's some ActiveRecord magic you can do to make the object/relational translation a little more automatic, but I don't remember what it's called at the moment.

Upvotes: 1

Related Questions