Rails: many to many relationship join table design - ruby-on-rails

Model Material & Manager is many to many relationship,
this means Material needs to be checked by many managers,managers check many materials.
ManageMaterial is join table with attributes
material_id
manager_id
I load some data into join table like this
id manager_id material_id
---------- ---------- -----------
1 6 52
2 8 52
3 2 12
4 5 12
Now I want to show what materials are being checked, in this example I just want one item with material_id = 52, but if I do #items = ManageMaterial.all , it will return two items.
How to solve this problem?

If you want to get ManageMaterials without duplication:
#items = ManageMaterial.select("DISTINCT(material_id)")
If you want a single ManageMaterial with material_id:
#items = ManageMaterial.find_by_material_id(52)

Related

MS Access: compare multiple query results from one table against the results of a query on the same table

I am building an ms access db to manage part numbers of mixtures. It’s pretty much a bill of materials. I have a table, tblMixtures that references itself in the PreMixture field. I set this up so that a mixture can be a pre-mixture in another mixture, which can in turn be a pre-mixture in another mixture, etc. Each PartNumber in tblMixture is related to many Components in tblMixtureComponents by the PartNumber. The Components and their associated data is stored in tblComponentData. I have put in example data in the tables below.
tblMixtures
PartNumber
Description
PreMixtures
1
Mixture 1
4, 5
2
Mixture 2
4, 6
3
Mixture 3
4
Mixture 4
3
5
Mixture 5
6
Mixture 6
tblMixtureComponents
ID
PartNumber
Component
Concentration
1
1
A
20%
2
1
B
40%
3
1
C
40%
4
2
A
40%
5
2
B
30%
6
2
D
30%
tblComponentData
ID
Name
Density
Category
1
A
1.5
O
2
B
2
F
3
C
2.5
I
4
D
1
F
I have built the queries needed to pull the information together for the final mixture and even display the details of the pre-mixtures and components used for each mixture. However, with literally tens of thousands of part numbers, there can be a lot of overlap in pre-mixtures used for mixtures. In other words, Mixture 4 can be used as a pre-mixture for Mixture 1 and Mixture 2 and a lot more. I want to build a query that will identify all possible mixtures that can be used as a pre-mixture in a selected mixture. So I want a list of all the mixtures that have the same components or subset of components as the selected mixtures. The pre-mixture doesn’t have to have all the components in the mixture, but it can’t have any components that are not in the mixture.
If you haven't solved it yet...
The PreMixtures column storing a collection of data is a sign that you need to "Normalize" your database design a little more. If you are going to be getting premixture data from a query then you do not need to store this as table data. If you did, you would be forced to update the premix data every time your mixtures or components changed.
Also we need to adress that tblMixtures doesn't have an id field. Consider the following table changes:
tblMixture:
id
description
1
Mixture 1
2
Mixture 2
3
Mixture 3
tblMixtureComponent:
id
mixtureId
componentId
1
1
A
2
1
B
3
1
C
4
2
A
5
2
B
6
2
D
7
3
A
8
4
B
I personally like to use column naming that exposes primary to foreign key relationships. tblMixtures.id is clearly related to tblMixtureComponenets.mixtureId. I am lazy so i would also probably abreviate everything too.
Now as far as the query, first lets get the components of mixture 1:
SELECT tblMixtureComponent.mixtureId, tblMixtureComponent.componentId
FROM tblMixtureComponent
WHERE tblMixtureComponent.mixtureId = 1
Should return:
mixtureId
componentId
1
A
1
B
1
C
We could change the WHERE clause to the id of any mixture we wanted. Next we need to get all the mixture ids with bad components. So we will build a join to compare around the last query:
SELECT tblMixtureComponent.mixtureId
FROM tblMixtureComponenet LEFT JOIN
(SELECT tblMixtureComponent.mixtureId,
tblMixtureComponent.componentId
FROM tblMixtureComponent
WHERE tblMixtureComponent.mixtureId = 1) AS GoodComp
ON tblMixtures.componentId = GoodComp.componentId
WHERE GoodComp.componentId Is Null
Should return:
mixtureId
2
Great so now we have ids of all the mixtures we don't want. Lets add another join to get the inverse:
SELECT tblMixture.id
FROM tblMix LEFT JOIN
(SELECT tblMixtureComponent.mixtureId
FROM tblMixtureComponenet LEFT JOIN
(SELECT tblMixtureComponent.mixtureId,
tblMixtureComponent.componentId
FROM tblMixtureComponent
WHERE tblMixtureComponent.mixtureId = 1) AS GoodComp
ON tblMixtures.componentId = GoodComp.componentId
WHERE GoodComp.componentId Is Null) AS BadMix
ON tblMixtures.id = BadMix.mixtureId
WHERE BadMix.mixtureId = Null AND tblMixture.id <> 1
Should return:
mixtureId
3
4
Whats left is all of the ids of that have similar components but not nonsimilar components to mixture 1.
Sorry i did this on a phone...

Sort a table using the total of other tables

2 tables: memberships and week_scores
Membership has_many :week_scores
WeekScore belongs_to :membership
Every membership has 16 week_scores
Every week_score table has a score column that has an integer from 0 to 20.
So just to be clear all memberships have 16 week_scores and I want to display a leaderboard table of all members of the group sorted by the total score of all their 16 week_scores tables.
It should look something like this
Username | Score
David | 114
Rick | 97
Mike | 95
...
The score column should be a sum of all the week_scores one user has so in case of David it was
week_score.score 1: 15
week_score.score 2: 12
week_score.score 3: 14
...
week_score.score 16: 9
total: 114
If the name of the post is not good let me know.
One way of doing this is with an subselect:
subselect = "SELECT SUM(score) FROM week_scores WHERE membership_id=memberships.id"
#memberships = Membership.
select("memberships.*, (#{subselect}) AS total_score").
order("total_score DESC")
The additional column specified in the select clause (total_score) will be available on the returned membership instances as if it were a “real” attribute, so calling something like #memberships.first.total_score will work.
(Note that I extracted the subselect into a separate variable only to make the code more readable, it is of course also possible to have it inline instead.)

Two references of the same model in another Rails: 4

I ask if it is good to have two references of one model in another and if it can do it how do I do it?
Problem: I have a record that will be controlled by two users (both always different users) and I need to have them see the records they have.
picture example:
example
The idea is that both can have access to the same registry and no one else can
you are trying to achieve many to many association, I would suggest you to use has_many_through association. you can read about it over here.
your tables will be like:
User:
id, email, name and other fields related to user
Box:
id, name and Fields related to boxes
User_Boxes: (Join table for mapping users with boxes, to do what you're trying to achieve)
id, user_id, box_id
so,
according to your diagram:
let the id's of boxes in box table be:
box home
box 2
box closet
box keys
Your mapping table would look like:
id box_id user_id
1 1 1
2 1 3
3 2 5
4 2 9
5 3 1
6 3 9
7 4 7
8 4 2
I hope this will solve your problem.

Get all records from one table that are not in either column of a second table

I have a Player model and a Match model. Each Match has a winner_id and a loser_id for the winning and losing Player.
How can I get all players that have never been in a match?
I.e. get all player ids, that are in neither the winner_id nor the loser_id column.
I'm using Rails 4.
Players
-------------
id
1
2
3
4
5
6
7
Matches
-------------
winner_id loser_id
1 2
1 3
1 4
So the result should be players 5, 6, and 7.
Player.where.not(id: Match.pluck(:winner_id,:loser_id).flatten.uniq)
There might be some better way also. but you can do it like this also:
ids = Matche.select(:winner_id).distinct.map{|match| match.winner_id} + Matche.select(:loser_id).distinct.map{|match| match.loser_id}
#players = Player.where.not(id: ids)

link to products belonging to more than one category in prestashop?

Ive got a category structure like this:
Category 1
Category 2
Category 3
Category 4
Category 5
Category 6
Category 7
Category 8
And wanna show all the products that belong to Category 8 AND Category 3. Category 8 is not a child of 3.
How can I do it? How (first of all) can I build the relative link?
You have several ways to achieve this, however in terms of performance it mostly depends on the size of your catalog.
Here is an example written in SQL that would be very fast and also make sure the selected products are active:
$products_categories = Db::getInstance()->ExecuteS('
SELECT cp.id_product, pl.name product_name
FROM '._DB_PREFIX_.'category_product cp
LEFT JOIN '._DB_PREFIX_.'category c ON (c.id_category = cp.id_category)
LEFT JOIN '._DB_PREFIX_.'product p ON (p.id_product = cp.id_product)
LEFT JOIN '._DB_PREFIX_.'product_lang pl ON (pl.id_product = p.id_product)
WHERE cp.id_category = 3 AND p.active = 1 AND c.active = 1 and pl.id_lang = 1 AND cp.id_product IN (SELECT id_product FROM '._DB_PREFIX_.'category_product WHERE id_category = 8)');

Resources