I'm very new to the rails framework and want to know how to generate a model based on an existing table. For example, I have a table named person and want to generate the model based on the columns from that table. However, whenever I use "ruby script/generate model Person --skip-migration it creates an empty table named people and creates the model after that. Is there a way to generate a model after a table named person?
Thanks.
Rails is very opinionated, so if you have a table called "person" and you want the corresponding model to be called Person, you need to tell Rails explicitly not to be so clever (otherwise, it will assume that it needs to look for the plural of the model name for the table name).
class Person < ActiveRecord::Base
set_table_name 'person'
end
If your table's primary key isn't called "id", then you'll need to specify that, too...
set_primary_key 'person_id'
You may also need to specify a different autoincrement sequence name, depending on your database.
There's not a way that I know of to automatically generate a model from an existing legacy table, but this should get you most of the way there.
Related
I have a model in Rails that I would like to use as a basis for another.
For example model: parent will be the template for model child.
I can see two possible options:
(1) Inherit from the first model and then add additional columns
Class Parent < ActiveRecord::Base
Class Child < Parent
(2) Copy the model.rb file and add new features
Class Child < ActiveRecord::Base
In both cases the "Rails" part of the model is created, but what about the database table? I could create the table using create table child as select * from parent where 1=2 and then create migrations to add the additional columns, but it doesn't seem like the "Rails way".
Is there an easy way to create a migration based on an existing table. or am I barking up the wrong tree entirely?
Your (1) is called single table inheritance (STI). Basically you use one table that has both the fields of the parent and the child. You'll also need a column called type to identify the type of the object.
Without more details I can't say if it's a good idea to use STI in your case, but (2) copying model.rb certainly doesn't seem right.
New Rails guy here...
I have a SimpleForm model which belongs to a Parts table belonging to another schema that's not Rails application.
What's the best way to model this association so that my form can do a lookup of the Parts table for part_id and the model can validate the part_id foreign key against the legacy Parts table?
possibilities:
create a database view and activerecord model in rails app?
create a readonly model with query/connection to Parts table?
Please be specific, as I really don't know much within Rails.
I am using Rails with Oracle and Windows, so any solution has to work with these.
Thanks in advance!
I ended up using database migration to create a database view and created readonly model for it.
In my SimpleForm, setup belongs_to relationship to the new Parts model and validates_presence_of to enforce the foreign constraint on inserts and edits.
Looks like this is pretty good way to do readonly foreign key reference by granting only "select" permission to legacy table and also setting Rails model to readonly.
I have a Record model (Active Record) that stores some custom logs.
Record is in polymorphic association with all the other model in my app, and I can effectively log what I want hooking my Record methods in the other controllers.
What I need:
To have the logs in a separate database.
So I have to:
Be able to manage two different databases in my apllication (one is Postgres/ActiveRecord and the other one is MongoDB/MongoMapper)
Generate a polymorphic association between my Record model, now with MongoMapper, and the rest of my Active Record models.
That way I can persist my logs to the MongoDB database.
Thanks.
Yes this can be done.
To create a polymorphic association you need both the class and an id. Idiomatically the fields will be named <assoc>_type and <assoc>_id‡. You will need to do some wiring up to make everything work.
Create a MongoMapper::Document Class with the keys <assoc>_type and <assoc>_id with the correct types (I believe MongoMapper allows Class as a key type) along with any other keys you may need.
Define the method <assoc> and <assoc>=
def assoc
assoc_type.find(assoc_id)
end
def assoc=(input)
assoc_type = input.class #STI makes this more complicated we must store the base class
asspc_id = input.id
end
Possibly add a method to your ActiveRecord models allowing them to access you MongoMapper logging class. If there are a lot, you may want to build a module and include it in all the classes that need that kind of functionality.
‡ replace with something meaningful for you application like 'reference' or 'subject'
I have to model an association structure and the association is divided into divisions/subdivisions/sections etc. So I've created a simple Entity-Attribute Model:
I'd like to use rail's single-table-inheritance but it seems like this works only if the type column is a string. My question is how to achieve this with my approach? Since I'm using a foreign key as "type" I'd have to query the "type name" first. Has anybody done this before?
I would recommend adding a String "type" attribute to your structure table to satisfy single table inheritance, and to add before_save callbacks to set correct values on either table.
Say you have a StructureType with name "Basic". In Rails that means you'd want to have class hierarchy:
Structure < ActiveRecord::Base
BasicStructure < Structure
In Structure class add:
before_create :set_structure_type_fk
def set_structure_type_fk
self.structure_type = StructureType.find_by_name(\
self.class.name.gsub(/Structure/, '').downcase)
end
Hope this helps.
Note that this approach means that StructureType.name should be immutable: once created it should never be changed, except by a database migration that updates both tables correspondingly.
K
I have a user table, and a teacher that I newly created. The teacher is sub class of user, so, I use scaffold generator to generate the teacher table, than, I modify the model to do teacher is subclass of user. After all that, I did a db:migrate. Then, I go to
http://localhost:3000/teachers/new
It shows an error:
undefined method `teacherSalary' for #<Teacher:0x103331900>
So, my question is what did I do wrong? I want to create a page for doing user register, the user can ONLY be a teacher / student. But I can't add a teacher record ... ... Moreover, I go to
http://localhost:3000/users/new
I want to have a combo box that allow user register their user to be a "teacher" or a "student". But everything seems not work like I expected. What I need to do? Thank you very very much for your help.
Within your database you should have a single table called users. This table should have a string column which by default is called type. If you use another name for this column then you will have to set the inheritance column name manually using self.inheritance_column = "column_name"
Within your application you have three models, User, Student and Teacher. User inherits from ActiveRecord::Base as usual, Student and Teacher both inherit from User.
You should then be able to instantiate new Teacher and Student objects. Internally this works by writing the model name to the type field on the user tables and then when you use Student.find it adds a clause to the SQL to only return rows where the type = 'Student'
You can add shared behaviour to the User class, e.g. validations etc then add additional behaviour to the inherited classes.
A fuller description of how STI works can be found in Martin Fowlers Book(Patterns of Enterprise Application Architecture).
I found this definition really handy:
STI means one table contains the data of more than one model, usually differentiated by the "type" column. ("users" table contains data for the models "Teacher", ""Pupil", "Employee", "Assistant", etc.)
Keeps similar models in the same table instead of creating new ones.
A Polymorphic Association means that one model can be associated with more than one other model(Comment can belong to post, image, file, user_type...)
To prevent foreign key conflicts, the association is reperesented with the *_id and *_type columns instead of only *_id.
For what you have here , I am not sure if STI is the best way go . STI should generally be used when there is a OO like inheritance and the Models have the same Attribute but different behaviour . In your case Teacher and Student can sure have a few shared attributed , but they are also bound to have different ones as well .
You might want to experiment with a polymorphic association as well .