i currently have 3 tables and 3 join tables
Users
Projects
Materials
a User has many Projects and Materials
a Project has many Users and Materials
a Material has many Projects and Users
each of them have their respective join tables to one another
say a Material has a column "name" and "amount". How can i form the associations so that for the same instance of materials, it has a different amount for a Project and a User?
I am currently storing "amount" in their join tables so a UserMaterial and a ProjectMaterial has different "amounts". The issue with that is when i query the materials from a User, I would have to make 2 separate queries. One to get an array of the Material names from the Materials table,
user.materials
and another to get an array of the amounts from the UserMaterial.
user.usermaterials
Is there an issue/improvement with my associations? or is there a query method to combine those 2 arrays, attaching the correct name and amount to the correct id?
Any assistance is appreciated. Thank you
If you query on user.materials, that will have to join through user_materials. If you use includes, it can get both in one query.
user_materials = #user.user_materials.includes(:material)
Then, when you loop through, the user_material.material association will already be loaded and ready for you.
user_materials.each do |um|
name = um.material.name # material is already loaded
end
Related
I'm having a very difficult time setting up model/table relationships for a hobby project I'm working on. What I have is an order, the order will have one or many packages, each package has one or many products, each product will have one area it is assigned to. There can be multiple of the same product on the order and in the same package but each will have a different area
and a different quantity. I'm struggling to determine how the relationships are set up.
At the end of the day I need to run a report that shows me the order details listing all packages on the order and all the products and areas contained in each package. I also need a report that shows me the order and a sum of all the quantities for each product on the order (no packages on this one). I'm using Rails ActiveRecord I think believe there will be a couple polymorphic relationships, but I'm struggling to identify them as this is outside of my simple "everything has a one-to-many relationship" thinking.
How can I put these tables together in an intelligent manner? I have searched for similar schema diagrams without much success.
This is the basics of what I am thinking of for relationships, but I'm not sure what the Rails models will look like. It seems like every relationship from orders down is polymorphic; how do I nest these relationships in Rails?
I think you need some JOIN tables.
An Order can have many Products; a Product can be added to many Orders.
In that case you'd have a JOIN table that would have two columns: primary keys for Order and Product. The two together would be a composite primary key.
I don't know what Area means in your schema, but perhaps this suggestion will break the mental logjam for you.
I have a Rails application featuring a city in the US. I'm working on a database process that will feature businesses that pay to be on the website. The goal is to feature businesses within an hour's drive of the city's location in order to make visitors aware of what is available. My goal is to group the businesses by city where the businesses in the city are listed first then the businesses from the next closest city are displayed. I want the cities to be listed by distance and the businesses within the city group to be listed by the business name.
I have two tables that I want to join in order to accomplish this.
city (has_many :businesses) - name, distance
business (belongs_to :city) - name, city_id, other columns
I know I can do something like the statement below that should only show data where business rows exist for a city row.
#businesses = City.order(“distance ASC").joins('JOIN businesses ON businesses.city_id = cities.id')
I would like to add order by businesses.name. I've seen an example ORDER BY a.Date, p.title which referencing columns from two databases.
ORDER BY a.Date, p.title
Can I add code to my existing statement to order businesses by name or will I have to embed SQL code to do this? I have seen examples with other databases doing this but either the answer is not Rails specific or not using PostgreSQL.
After lots more research I was finally able to get this working the way I wanted to.
Using .joins(:businesses) did not yield anything because it only included the columns for City aka BusinessCity and no columns for Business. I found that you have to use .pluck or .select to get access to the columns from the table you are joining. This is something I did not want to do because I foresee more columns being added in the future.
I ended up making Business the main table instead of BusinessCity as my starting point since I was listing data from Business on my view as stated in my initial question. When I did this I could not use the .joins(:business_cities) clause because it said the relation did not exist. I decided to go back to what I had originally started with using Business as the main table.
I came up with the following statement that provides all the columns from both tables ordered by distance on the BusinessCity table and name on the Business table. I was successful in added .where clauses as needed to accommodate the search functionality on my view.
#businesses = Business.joins("JOIN business_cities ON business_cities.id = businesses.business_city_id").order("business_cities.distance, businesses.name")
I have three tables: projects, technologies, and projects_technologies (a map from project IDs to/from technology IDs). I have two models: projects and technologies. Projects have and belong to many (HABTM) technologies and vice versa. Now I'm trying to get all the names (or active records, if there's a way to do that) of technologies that belong to a given project. Here's the SQL statement I've made, using 5 as the given project ID:
SELECT name FROM technologies WHERE id IN (
SELECT projects_technologies.technology_id FROM projects_technologies
WHERE projects_technologies.project_id = 5
);
I could just connect to the database and run the query, but since I already have the models set up with HABTM relationships, I'm wondering if there's a "Rails way" to execute this. I've been looking at this documentation, http://guides.rubyonrails.org/active_record_querying.html, but I can't figure out if and how I can apply that to this kind of query.
UPDATE
Turns out all I needed was this:
Project.find(5).technologies
The equivalent active record query would be
Technology.select('name').where("id IN (?)", ProjectTechnology.where("project_id = ?", 5).pluck(:technology_id))
Hope this helps!
I'm working on an application where we have a survey, and the survey can be run at multiple locations, and each location could have a different staff member. Logically, makes sense to create a three column join table between Survey, Location, and Trainer. Seems easy enough.
The problem I'm having is associating all three in the form when submitting. I know how to create an array of locations and an array of staff members, but not clear on how to associate those two together.
Selecting both the locations and staff members is done through a collection select.
After that, I feel pretty comfortable I can write the necessary code to create the records in the join table, just looking for some ideas how to structure the HTML and/or form_for objects.
In Rails 4, I have a project in which I've set up three models with the following many-to-many relationships:
An Item
has_and_belongs_to_many categories
has_and_belongs_to_many tags
A Category
has_and_belongs_to_many items
A Tag
has_and_belongs_to_many items
And while it's easy to select an Item and automatically get all associated categories and tags, there are some situations in which I'd want to select items AND their associated categories, but NOT their tags. In these cases, I'd like to avoid doing extra database joins against the Tags table and ItemsTags join table. Can anyone help me with the correct find syntax to only join Items to categories? (Side note: I'm also planning on adding 10 additional many-to-many relationships between items and other models, but I'm just simplifying the scenario for this question. In the end, I'm trying to avoid doing a join with an excessive number of tables whenever I can.)
Thanks!
Rails will by default not load associated records unless you request it
Item.all will only fetch record from 'items' table
Then later in your code if you call item.categories that's the point when a query is performed to fetch all categories of this particular item. If you never call item.tags then the query to 'tags' table is never executed and the records are not fetch. Bottom line is: you can have as many associations as needed, as long as you don't explicitly call them they won't be loaded.
Side note about performance, rails offer several ways to join and include associated tables:
Item.include(:category).all Will trigger only 2 queries to fetch all items, and all associated categories.
Item.include(:category).joins(:category).all -> will trigger only 1 query joining the items and categories tables (but it may be slower than 2 requests)
So you have all control over what's loaded from the database. Those can apply for scope as well.