Reputation: 2391
I come from a Java background and I have started learning Ruby on Rails. Consider the following code mentioned in http://guides.rubyonrails.org/active_record_basics.html
class Product < ActiveRecord::Base
end
The guide mentions that this creates a model Product mapped to a table products (using the pluralized mechanism of ruby). It also mentions, 'By doing this you'll also have the ability to map the columns of each row in that table with the attributes of the instances of your model.'
But we did not declare any attributes inside the model Product. How does it know what are its attributes?
One assumption: Every attribute of table is made as an attribute of model. Is it true? Then, do we create the SQL table first? If I change the table later on (adding new columns, say) does it also change my model dynamically?
Upvotes: 6
Views: 3443
Reputation: 9485
The important distinction is that we're talking about ActiveRecord models, i. e. subclasses (direct and indirect) of ActiveRecord::Base
, those that use its persistence mechanism. The following is not true for Rails models in general. But then again, for non-AR models the question makes no sense :)
Every attribute of table is made as an attribute of model. Is it true?
Yes.
Then, do we create the SQL table first?
Exactly. rails g model
creates a model file and a migration that contains a declaration for a table behind the model. So before using your model, you have to run the migration first.
If I change the table later on (adding new columns, say) does it also change my model dynamically?
Now that's tricky. It's most certainly true if the application is reloaded after the changes (e. g. in development mode this happens every now and then), since the model class will be reconstructed. So the answer is yes, most of the time.
This is, however, only about the internal structures of the model class (visible in e. g. Model.columns
) you don't always have to care about. When fetching data, all the columns of the result set will be mapped to attributes of the model objects. So this keeps even custom columns you specify in SELECT
s:
Thing.select(:id, "1 AS one").first.attributes
#> SELECT "things"."id", 1 AS one FROM "things" ORDER BY "things"."id" ASC LIMIT 1
# => {"id"=>1, "one"=>1}
Upvotes: 6
Reputation: 76774
It works like this:
class Product < ActiveRecord::Base
Product
is subclassed to ActiveRecord::Base
(you know subclassing from Java, right?).
ActiveRecord::Base
can be seen here:
Active Record objects don't specify their attributes directly, but rather infer them from # the table definition with which they're linked. Adding, removing, and changing attributes # and their type is done directly in the database. Any change is instantly reflected in the # Active Record objects. The mapping that binds a given Active Record class to a certain # database table will happen automatically in most common cases, but can be overwritten for the uncommon ones.
You can read through the other code; in short, it means that ActiveRecord uses the SQL schema to populate the respective attributes.
--
Because your model
is a Class
, ActiveRecord
will basically create a series of setter/getter
instance methods with the values from your db.
When you invoke said class, ActiveRecord::Base
will populate the respective instance methods with the values in your db, allowing you to call @product.name
etc.
Upvotes: 5
Reputation: 550
You only have to declare specific attributes in a migration (which creates the tables). Otherwise, ActiveRecord makes a some key assumptions:
name of the table = lowercase version of class name = products
primary key = id
Then it can use raw SQL when it starts the connection to get a list of attributes from the table:
DESCRIBE table products;
This gives it a full listing of the fields in the table. It sets up attributes in each instance of the class based on these fields.
Upvotes: 0
Reputation: 59232
Models in rails are just an easy way of binding the data from the database. Model is the data.
A model represents a table and will have all the columns of that table as its attributes.
The model in point is Product
. By rails conventions, this model is directly mapped to products
table in the database and will have all the attributes that the table has as its columns.
Models and tables are interlinked and models serve as an easy abstract layer over the actual data to provide ease of work and additional validations and stuff like that.
Upvotes: 1