I'm developing a rails project where I have one data model with multiple fields that are collection selects. I'd like to create another model to represent all of these collection select fields. So, for instance, my main data model has three collection select fields -- one for county, one for category, and one for classification. I could separate these into three separate data models, but that seems redundant since they all share the same characteristics. They have a type and a value, like a county is a county and it has a value of let's say Sonoma, just as category has a type of category and a value of let's say Winery. If you've ever used Drupal, I'm basically looking for the behavior of the taxonomy functionality.
So you see my dilemma: I need to separate these fields into three separate fields but they have very similar data structures. Any suggestions would be greatly appreciated.
This is a perfect case for single-table inheritance. Your problem is screaming for it.
Related
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've read so many Rails books/tutorials, but when it comes time to actually make the app, I keep tripping over myself, so I'm trying this little exercise to help me get it better.
I have an app with 3 classes (Link, Url, Visit) that have associations defined between them, such as has_one, belongs_to etc. This allows me to call methods like Link.url
If I were to convert this into an app with a single model, is it possible to create the convenience methods (such as Link.url) even though there are no relationships between models, because there is only one model.
This might not be the 'Rails way' but if you answer this question it'll help me get it more.
I guess another way to ask this is, do the Rails associations only exist because the tab
Thanks
Models exist to represent tables in a database. If you have 3 different conceptual objects, then you need 3 different models. Keeping those objects separate and in different tables/models is essential to good programming in any language. The relations are there to help you understand the correlation of each object to the others.
If you think all of data from each of the models can be represented in one table sensibly, then combine them in to one model with a name that encompasses all of the data. If you choose this option, you'll use columns for that one table which represent each of the pieces of data you need. Those column names come free in the model when you create the migration. A table with a column named "url" on a model named "Hit" could be used like this:
Hit.first.url
Hopefully we have good rails developer who can definitely give correct answer! For 2 days I didn't receive any valid answer for my question
I will explain in a very simple example
Customer is offering product. When he pushes create it gives form. Choose a category. Once he chooses another form will pop up.
Depending on a category, form should have totally different attributes.I can't have Product.new for every category. Reason is they have different attributes(Logicaly true). So do I have to create 100 models for 100 categories
Categories are : cars, apartments, coupons, books and many more
If you can give just one example I will be gratefull and call you expert
Thanks
It sounds like you're getting there. However, I wouldn't have a bunch of models like you're indicating in your question. I would say that you need a Product model and a Category model. The Category model will belong_to Product. The Product model would have many Categories. The Category model can use the acts_as_tree gem so that you can have categories and subcategories. Use javascript or jQuery (there was a recent Railscasts on this) to dynamically change and post a different field with a set of choices based on what was chosen.
EDIT:
I would have three Models; Product, Category, Specification
Product has many Categories
Product has many Specifications through Categories
Category belongs to Product
Category has many Specifications
Specification belongs to Category
This way I can create a product that has several categories. I can create several categories that have several specifications. Specifications are linked to the respective category. This will allow you to have three models and limited number of classes. Once your project is complete, new categories and specifications can be maintained by a web admin instead of a programmer.
This isn't the answer you want, but you're going to need a lot of models.
The attributes associated with an apartment (square meters, utilities, floor of building) are completely different from the attributes associated with a car (make, model, mileage, condition) which are completely different from a book (title, author, publisher, edition, etc). These items are so fundamentally different that there is no way to manage them in a single model.
That being said, there may be a core collection of attributes that might be associated with a product that is for sale (seller, price, terms). You have basically two paths forward:
You could decide to use Single Table Inheritance. In this case, you'd create an abstract class that defines the attributes that are common to all products that you are selling (seller, price, item). You'd then add a "type" column to your database that would be used to determine what type of product it is (mapped to your categories), and define all of the possible attributes in a single table.
You could choose a core set of attributes, and use these as a part of any other object that is considered a product. You'd have multiple tables that would have the full record for any given object.
Without knowing a lot of details about your application, it's hard to make a specific recommendation about which approach is right for you. Your best bet at this point is to spend a lot of time on google with "single table inheritance rails" and "multi table inheritance rails" and figure out which one is right for you (though my gut says multi table).
In some of my forms I have to provide a dropdown where users can select some districts. The thing is, there will always be a fixed number of districts ( 31 in this case ). Should I create a model named District having only a string field,populate it with the data and be done with it?
It's content will not modify over time. Is there another way?
You should take a look at jnunemakers scam-gem. It mimics the AR for you and lets you define the models in your Rails app without a backing database/table.
I use this whenever I want something to do psuedo belongs to/has many relationships, but do not want to back a model with a database as the data does not change often, if ever.
Making a table-backed model is the simplest way. Otherwise you're going to end up implementing half of an AR model anyway, because you'll want to use collection_select at some point.
I guess it depends on how you want to store the districts and whether you want to do any querying etc.
For example, you could just have the list of districts as a constant, then store them as a string in your models (not very elegant), or as you say you could create a model and use active record associations - this would allow you to easily query on districts etc.
I'm programming a website that allows users to post classified ads with detailed fields for different types of items they are selling. However, I have a question about the best database schema.
The site features many categories (eg. Cars, Computers, Cameras) and each category of ads have their own distinct fields. For example, Cars have attributes such as number of doors, make, model, and horsepower while Computers have attributes such as CPU, RAM, Motherboard Model, etc.
Now since they are all listings, I was thinking of a polymorphic approach, creating a parent LISTINGS table and a different child table for each of the different categories (COMPUTERS, CARS, CAMERAS). Each child table will have a listing_id that will link back to the LISTINGS TABLE. So when a listing is fetched, it would fetch a row from LISTINGS joined by the linked row in the associated child table.
LISTINGS
-listing_id
-user_id
-email_address
-date_created
-description
CARS
-car_id
-listing_id
-make
-model
-num_doors
-horsepower
COMPUTERS
-computer_id
-listing_id
-cpu
-ram
-motherboard_model
Now, is this schema a good design pattern or are there better ways to do this?
I considered single inheritance but quickly brushed off the thought because the table will get too large too quickly, but then another dilemma came to mind - if the user does a global search on all the listings, then that means I will have to query each child table separately. What happens if I have over 100 different categories, wouldn't it be inefficient?
I also thought of another approach where there is a master table (meta table) that defines the fields in each category and a field table that stores the field values of each listing, but would that go against database normalization?
How would sites like Kijiji do it?
Your database design is fine. No reason to change what you've got. I've seen the search done a few ways. One is to have your search stored procedure join all the tables you need to search across and index the columns to be searched. The second way I've seen it done which worked pretty well was to have a table that is only used for search which gets a copy of whatever fields that need to be searched. Then you would put triggers on those fields and update the search table.
They both have drawbacks but I preferred the first to the second.
EDIT
You need the following tables.
Categories
- Id
- Description
CategoriesListingsXref
- CategoryId
- ListingId
With this cross reference model you can join all your listings for a given category during search. Then add a little dynamic sql (because it's easier to understand) and build up your query to include the field(s) you want to search against and call execute on your query.
That's it.
EDIT 2
This seems to be a little bigger discussion that we can fin in these comment boxes. But, anything we would discuss can be understood by reading the following post.
http://www.sommarskog.se/dyn-search-2008.html
It is really complete and shows you more than 1 way of doing it with pro's and cons.
Good luck.
I think the design you have chosen will be good for the scenario you just described. Though I'm not sure if the sub class tables should have their own ID. Since a CAR is a Listing, it makes sense that the values are from the same "domain".
In the typical classified ads site, the data for an ad is written once and then is basically read-only. You can exploit this and store the data in a second set of tables that are more optimized for searching in just the way you want the users to search. Also, the search problem only really exists for a "general" search. Once the user picks a certain type of ad, you can switch to the sub class tables in order to do more advanced search (RAM > 4gb, cpu = overpowered).