I'm trying to develop a many-to-many relationship between tags (in the tags table) and items (in the items table) using a field of type integer[] on each item.
I know that Rails 4 (and Rails 3 via postgres_ext) has support for Postgres' arrays feature through the :array => true parameter, but I can't figure out how to combine them with Active Record associations.
Does has_many have an option for this? Is there a gem for this? Should I give up and just create a has_many :through relationship (though with the amount of relations I'm expecting this is probably unmanageable)?
At this point, there isn't a way to use relationships with arrays in Rails. Using the selected answer though, you will run into the N+1 select issue. Say you get your posts and then the tags for it on each post with "tags" method defined in the class. For each post you call the tags on, you will incur another database hit.
Hopefully, this will change in the future and we can get rid of the join table (especially given that Postgres 9.4 will include support for foreign keys in Arrays).
All you really need to do is
def tags
Tag.where(id: tag_ids)
end
def add_tag(tag)
self.tag_ids += [tag.id] unless tag_ids.include?(tag.id)
end
At least that's what I do at the moment. I do some pretty cool stuff with hashes (hstore) as well with permissions. One way of handling tags is to create the has_many through and persist the tags in a string array column as they are added for convenience and performance (not having to query the 2 related tables just to get the names out). I you don't necessarily have to use active record to do cool stuff with the database.
Related
I'm trying to model the following relationships between entities, mainly consisting of a partial, disjoint generalization.
original EERD
'mapped' to relational
Since I didn't need the subclasses to have any particular attributes I decided to use the "single table inheritance" approach, added the "type" field and moved the relationships towards the parent.
After that I had two choices to make:
1- type for the "business type" attribute
2- way to constraint participation to at most one of the 4 relationships based on the type attribute
For the sake of portability and extensibility I decided to implement no.1 as a lookup table (rather than enum or a hardcoded check).
About no.2 I figured the best way to enforce participation and exclusivity constraints on the four relationships would be a trigger.
The problem is that now I'm not really sure how to write a trigger function; for instance it would have to reference values inserted into business type, so I'd have to make sure those can't be changed or deleted in the future.
I feel like I'm doing something wrong so I wanted to ask for feedback before going further; is this a suitable approach in your opinion?
I found an interesting article describing a possible solution: it feels a bit like an 'hack' but it should be working
(it's intended for SQL Server, but it can be easily applied in postgres too).
EDIT:
It consists in adding a type field to the parent table, and then have every child table reference said field along with the parent's id by using a foreign key constraint (a UNIQUE constraint on this pair of fields has to be added beforehand, since FKs must be unique).
Now in order to force the type field to match the table it belongs to, one adds a check constraint/always generated value ensuring that the type column always has the same value
(eg: CHECK(Business_type_id = 1) in the Husbandry table, where 1 represents 'husbandry' in the type lookup table).
The only issue is that it requires a whole column in every subclass, each containing the same generated value repeated over and over (waste of space?), and it may fall apart as soon as the IDs in the lookup table are modified
I am using go and pq to interface with my postgres database.
I have a simple user table which has basic fields. Id, name, type. My auxillary table, admin inherits from user and adds it's own field panel, and another one that is owner and adds owner. Whether that be using table inheritance, or a supporting table.
My question is if I hit and endpoint that points to user/1 at this point I don't know what type of user this person is yet here. I know we can use jwts and other ways to provide this from the front end. I'm more curious about if there is a way to figure out the user and it's type and query the additional fields in one query?
Ie. I hit the endpoint I would Select from users, get the type, then use that type to get the additional fields. So I would effectively be doing two queries on two tables to get the complete data. Is there a better solution of doing this? Is there some optimizations I could do.
A general parse.com relationship question really - using swift. I have a blogging app, for which there is a blog class, and a user class (along with a few others!) the blog class stores the associated user ID in a field for simplicity. Can I use includekey (or something similar) in a pfquery for the following;
firstly retrieve specific (or all) blog entries that match a criteria.
for each matching blog entry, check a field in the related user class for an option before returning the JSON list of entries
I suppose, sort of a subquery really, but wanted the whole thing to work in one pfquery if possible.
thanks!
Yes, you can do this with a relational query. The user stored in blog should be a pointer.
First create a query for the field in the user class, i.e.
userQuery.whereKey("age", greaterThan: 30)
(Do not execute this query)
Then, when adding constraints to your blog query, add
blogQuery.whereKey("user", matchesQuery: userQuery)
I want to implement content tagging using MongoDB. In a relational database, the best approach would be to have a many-to-many relation between the content (say, "products") and tags tables. But what is best approach with NoSQL databases?
Would it be better to put every tag in a tags array of the "content" document, or put references to tags in a string?
In most cases where you have a n:m relation in MongoDB, you should use embedding instead of referencing. So I would recommend you to have an array "tags" in each product with the tag names. I assume that looking at a single product will be the most frequent use-case in your system. This design will allow you to show the user a product with a list of tag names with a single database query.
When you need some additional meta-data about the tags which you don't want to bind to a product (like a long-text description of a tag), you could create an additional tags collection, where the name field gets an unique index for fast lookup and avoiding duplicates. When the user clicks on or hovers over a tag name, you can use an additional query to get the tag details.
A problematic case in this design is the situation when you want to delete or rename a tag. Then you have to edit every product which includes the tag. But because MongoDB doesn't know foreign keys with CASCADE ON DELETE like SQL databases, you will always have that problem when you have documents referencing one another.
Renaming tags could be made easier by storing objectIDs instead of names in the tag array of the product. But IDs have the disadvantage that they are useless for the user. You need to get the names of the tags to show a product page. That means that you have to request every single one from the tags collection, which requires an additional database query.
I have a many-to-many relationship between 2 entities in Entity Framework, like here . So, Employees and Projects. At one point, I would like to insert some Projects to a Employees entity in a specific order. By conserving the order I would like to know which was the first preference of the Employees for a Projects entity. The thing is that although I order the Student.Projectslist in the way I like before the insert, when selecting Employees.Projects.FirstOrDefault(), the entities are ordered after the ProjectsId and I don't get the first element I inserted. How can I conserve the order I want?
O course, I could make a new field PreferredProjects and save the other Projects in a random order, since only the preferred one is important for me. But this is not an option, being given the context of the current project's software design.
Thank you in advance...
It sounds like you simply want to have sorted child collection results when you do a query, rather than take full control of the insert order.
You can achieve that using the techniques described in Tip 1 of my tips series.
Hope this helps.
Alex
Program Manager Entity Framework Team.
Unfortunately, there is no easy solution. I have the same problem. The only solution is to save after adding each child item (project). This is the only way to save the order without using a new field column to sort input.
Try Employees.Projects.OrderBy(x => x).FirstOrDefault()