Linking fields in from between different models - ruby-on-rails

This question is related to: How to link form after creating rails join table
I Had a products model, with a categories field, however needed each category in individual rows rather than the comma separated rows they were in. So I created a Category and ProductCategory model, and added all appropriate associations.
How do I link up the categories field from the old products model to the new Category table so that when a user enter a new product and adds the category, it will save to the category table.

There is a great Railscast on setting up accepts_nested_attributes_for it should be just what you are looking for. I would do you a better service by just telling you to watch it, rather than replicate code.
http://railscasts.com/episodes/196-nested-model-form-part-1

Related

How do I save two models with has_many through on the same form

I've had this question about ruby on rails some time ago, and managed to solve it in some way:
The solution I've found is use nesting forms with the join model(fields_for), saving the third model within an external form and inserting its ID with ajax.
The problem is that the nested form is too big to nest inside Order form(main form).
I'm not satisfied with this solution, so here it is:
Let's say I have three models:
Order
Order-List (has_many through model)
List
So, the Order contains different Lists, and each List has Items (With other has_many relationships between).
In an example, know that I can save the information about the has_many through model on the same form, but how do I save an Order AND a new List(on the same form)?
Thanks in advance!

rails when/how to use nested resources

I have a rails app. Users can create products that will be listed on products index page (including some data about the user who posted it) and everybody can see the list on app/products.html.
What is the best way to implement this? Should I do it with nested resources (user has many products) in which case I can use product.user.name for displaying the user name or should I create an independent class so when user creates a product, some user attributes (name, etc.) will get saved in the product table.
Your mixing together quite a few different concepts here.
Nested routes
In REST you have a concept of nested resources which is expressed though URIs such as:
posts/:post_id/comments # comment that belong to a resource.
Which tells us that there is a "has many" relation between post and comments.
The best practice here is that:
Don't nest if you don't need to.
Never nest more than 1 level deep. posts/:post_id/comments/:comment_id/replies for example should be comments/:comment_id/replies.
Associations and domain modeling
Domain modeling on the other hand is how your models fit together. In ActiveRecord each model class is backed by a database table.
Each model should correspond to a single type of object in your problem domain. So in your case you would have a User class and Products class.
They would be linked by a products.user_id column. So no - you should not store users attributes in the products table.

Create form for multiple models in Rails

I'm very new to Rails so sorry in advance if this is a fairly obvious question.
I need to make a form that can create records for multiple models in Rails. My models are categories of grocery-store items: Produce, Meat, Dairy, etc.
In my create form, I want the user to be able to create a product by selecting which model it belongs to and then have the controller insert the record into the appropriate DB table.
so my questions are:
should I still define each model as a resource?
is it possible to use one controller to add, update, delete for all of the product models?
Have you considered just making a category column in your items model? If not you could use active record associations to accomplish something like this. See the documentation at:
http://guides.rubyonrails.org/association_basics.html

Validate many-to-many circle

I have this object association here:
Entry *--1 Category *--1 Project *--* User 1--* Entry
Explanation: An entry belongs to a category which has many entries, a category belongs to a project which has many categories - many users can have many projects. This user also has many entries and one entry belongs to one user.
When an entry is saved with a category and user association, I want to make sure, that the category belongs to a project a user is assigned to.
I thought about implementing a custom validator that fetches the project of the worklog and checks if it's in the list of the user's projects.
Is there a more Rails-like way to it or am I on the right track?

How does the Rails' single table inheritance works?

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 .

Resources