Lets say i have 2 models Quote and Invoice and they share common fields. How do you convert a Quote to an Invoice. How would that work around the models and controllers with creating a new Invoice based on the values already stored in the Invoice?
Related
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?
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 SELECTs:
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}
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.
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.
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.
I have a problem with habtm on a single model in rails.
Example:
Let us say i have a User model with two roles "Student" and "teacher". User model is common for two roles. Now
Each student can be associated to many teachers
Each teacher can be associated to many students
In rails notation, their should be habtm between teacher and student
How this can be achieved with single table.
Thanks,
Aashish
It can't be done with a single table. In a many-to-many relationship, no matter what, you always need a table where you store the associations.
In your case, given the association seems to be parent/child, then you just need two tables instead of one.
How to implement it, it depends on your database structure and data organization. You should create an users_users table (as part of the habtm) and configure the references accordingly. If the user table, as it seems to be, is also used for STI, then the configuration may change a little bit.
I am working on an application that allows various people from different departments in a company log in and edit a form. Each department has specific fields in the form that only they are allowed to edit and view.
Would it be more organized code if I create one model for the entire set of fields and based on who logs in, render a different form containing the necessary fields? Or would it be better to split the department-specific fields into their own models and then based on who logs in, render a form containing their specific fields and relate the records from different departments together through a foreign key of some sort?
"It depends" is probably the best answer.
How many fields do you have? How much logic exists per department form type?
If you split all the fields to separate models (and corresponding tables) it will become a hassle if you ever want a full overview of the forms after they have been filled in, because they would be in separate tables. You'd have to go through every association of the form to get the full form.
If you still want to split them, because you have a lot of logic per department, you could point all your models to one 'main' table that contains all the fields, using table_name. That way you have all the data in one table and you can easily retrieve it. However, you'd also have to save the type of form in order to retrieve it in the correct model, probably more trouble than it's worth. (If it's the best thing to save all your fields in one table depends as well, how often does it get retrieved or does it get inserted/updated more often.)
Simple forms will probably fit just fine in one model. Unless you have a lot of non-sharable code per department it probably isn't worth it to split the form into separate models. If you do split the form into models you probably should create one main form model and have the department models extend it for whatever bit of reusable form logic there is.
After all that, I would say, I prefer simplicity so I'd probably save it in one model.
I'd split the fields and then you can setup your models with accepts_nested_attributes_for to build your form appropriately.
I have a model called Application, and I need users to be able to add their classes and grades to a column in the database. Is there a way to do this without creating a separate model?
I need users able to press "Add Grades" as many times as they like, creating two new form fields to enter in the class name and grade they got.
I recommend creating a grades model - it is the Rails way. A Grade can belong to an Application. An Application can have many Grades. Each Grade can then have two attributes - a class and a grade.
Alternatively, you can store all your grades for a single application in a single column, but you'll be responsible for the format that they're saved in, ensuring that they are serialized at some point prior to being saved, parsing when you load each Application, etc. Finally, you'll be coming up with additional fields to deal with the parsed grades.
All of this can be avoided by simply creating the Grade model and setting up the appropriate relationship with the Application model.
I have Events, Documents, and Surveys which all need to be able to link to one another, I was planning on having a linking table with four columns as follows:
link_elements{
element1_type CHAR(1)
element1_id INTEGER
element2_type CHAR(1)
element2_id INTEGER
}
The problem is I can't figure out how to make the model in RoR so that I can use the element type field to identify which table the corresponding element id belongs to (Documents, Events, or Surveys). I'm really new to Ruby and any help would really be appreciated.
I think you're just looking for the has_many and belongs_to associations.
If you have an Event model, a Document model, and a Survey model, then you can specify in their respective .rb files in the Models folder if they have or belong to the other models.
Ex: you want Surveys to belong to Documents. In Survey.rb, add the line belongs_to :document. In Document.rb, add the line has_many :surveys.
Now if you add a new "document_id" column in the Surveys table, it will look for a a Document object that corresponds to the id integer in that column.
For more info check out the Rails API.