How do I create a polymorphic relation using the MySQL Workbench tool? I want to be able to handle something like what Rails gives me with:
class Example < ActiveRecord::Base
belongs_to :someone, polymorphic: true
end
class PolyOne < ActiveRecord::Base
has_many :examples, as: :someone
end
class PolyTwo < ActiveRecord::Base
has_many :examples, as: :someone
end
If you utilize the "Place a relationship using existing columns," the icon with the 1:N and dropper, you'll be able to accomplish this task. In the examples table (Rails always pluralizes), make sure you have two columns: someone_id and someone_type. In the polymorphic tables, you should already have an id column. Then, you choose the tool mentioned at first (1:N with dropper) and click on someone_id followed by the id of the polymorphic table. This will create a new 1:N relationship between those two fields without inserting any new fields into the tables. Repeat this process for each connected polymorphic table. It will then represent the polymorphic relationship that Rails uses. If you are trying to mimic this on your own without Rails, you'll need to be sure to set the someone_id and someone_type appropriately so that you can follow the polymorphic relationship properly.
Related
I am trying to implement a number of base/sub classes using Entity Framework, database first. Following some online tutorials, I have decided to attempt TPT inheritance.
On the database, I have a base class table 'Location', and two sub class tables: 'StreetAddress' and 'RuralRouteAddress'. I have defined a foreign key constraint between the sub class tables and the base class table on their primary keys. 'Location's Primary Key is an auto-increment column, and the two sub class tables' primary keys are not auto-increment.
In Entity Framework, I defined the 'Base Type' of the two sub classes as 'Location'. I then deleted the associations (and their corresponding navigation properties) from the model. I also deleted the ID column mappings from the sub classes, as ID is now inherited from the 'Location' base class.
This seems to have worked. I haven't tried updating/inserting, but querying returns the data with proper inheritance in place.
My problem is that, whenever I 'Update Model from Database', he inheritance association lines stay, but the FK associations between the base class and the sub classes are brought back... . I then have to delete them, and realign the association lines on my diagram (I'm a bit picky about the layout of the model diagram).
This isn't so bad, but the project that I would like to use TPT inheritance in has a lot of inheritance. Having to delete a ton of associations and reorganize my entire diagram every time I update the model is not very appealing.
Did I do something wrong when I implemented inheritance? Is there a way to ignore/exclude certain associations from being created when updating the model?
The relationships you define in the database will always reappear when you update the model from the database. This is by design. If you want to have classes in the model that have a different relationship structure, try creating a complex model from a stored procedure that selects all the columns (or all the columns you want) from the base table. Import that procedure and in the Function Imports, edit the return type by creating a new complex type, or even just renaming the result that EF automatically creates. Then add your associations on that type, and use it as the base type for your inherited classes.
The good part of this is that you can adjust the type structure to match any table changes by editing the stored procedure, then using "Get Column Information" and "Update" to bring the complex type into line. It won't overwrite your associations because they aren't defined in the database, but it is almost as straightforward as using TPT.
Joey
I have the following associations:
class Student < ApplicationRecord
has_many :people_schools
has_many :schools, through: :people_schools
end
class PeopleSchool < ApplicationRecord
belongs_to :student
belongs_to :school
end
class School < ApplicationRecord
has_many :people_schools
has_many :students, through: :people_schools
end
I am trying to get a list of students organized by their school. I have tried the following:
Student.joins(:schools).all.group('schools.name')
but I get the following error:
ActiveRecord::StatementInvalid: PG::GroupingError: ERROR: column "students.id" must appear in the GROUP BY clause or be used in an aggregate function
How do I fix this?
When the association fires, it will generate a SQL query like
SELECT students.id, students. ...
FROM students
JOIN schools
ON ...
GROUP BY schools.name
In sql when grouping, a projection (SELECT) can only include columns that are grouped by or aggregations (e.g. MAX, MIN) of columns (regardless of whether they are grouped by). Therefore adding something like the following would turn it into a valid sql:
# column that is grouped by
Student.joins(:schools).group('schools.name').select('schools.name')
# aggregate function
Student.joins(:schools).group('schools.name').select('schools.name, COUNT(students.id)')
But how you want to fix it in your case depends on what you want to get out of the query.
In answer to the comment
Assuming a student is only member of a single school, which requires changing the association to a belongs_to :school (without the join table) or a has_one :school (with join table).
Student.includes(:school).group_by(&:school)
This will issue an SQL statement to get all students and their school (eager loaded for optimization). Only after the models (Student, School) are instantiated ruby objects, is the group_by method evaluated, which will return a Hash where the school is the key referencing an Array of students.
I have two sets of data that exhibit a one-to-one relationship.
I am not able to merge the two sets of data because:
Particular records may be present only in set A, only in set B, or both in set A and in set B; and
The association between records in set A and in set B is transient, meaning records can become associated and can become disassociated; and
The data in set A are processed differently than the data in set B; and
There are external architectural constraints.
When a record in set A is associated with a record in set B, I want to link the two records. When records are linked, the relationship must be one-to-one. How do I guarantee that the relationship is a one-to-one relationship?
The following code seems close, but I am new to working with Odoo and am uncertain how to analyze whether or not this approach guarantees a one-to-one relationship.
import openerp
class A(openerp.models.Model):
_name = 'set.a'
_sql_constraints = [
('set_b_id', 'unique("set_b_id")', 'Field set_b_id must be unique.'),
]
# Constrained to be unique (see SQL above) which essentially changes
# this end of the Many2one relationship to a One2one relationship. (The
# other end of the relationship must also be constrained.)
set_b_id = openerp.fields.Many2one(
comodel_name='set.b',
)
class B(openerp.models.Model):
_name = 'set.b'
# Constrained to tie with either zero keys or one key (see function
# below) which essentially changes this end of the One2many
# relationship to a One2one relationship. (The other end of the
# relationship must also be constrained.)
set_a_id = openerp.fields.One2many(
comodel_name='set.a',
inverse_name='set_b_id',
)
#openerp.api.constrains('set_a_id')
def _constrains_set_a_id(self):
if len(self.set_a_id) > 1:
raise openerp.exceptions.ValidationError('Additional linkage failed.')
Another approach might be to extend openerp.fields to recreate the previously deprecated One2one relationship, but I am not certain that could be done cleanly.
In your case basically the one-to-one relation is not available in Odoo 8.0 its totally deprecated one 7.0 or later version in Odoo (formally OpenERP).
so please my advice is that not to use one-to-one relation just use it as many2one instead and make to set your local as per your need.
I hope my answer may helpful for you :)
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.
Here is the senario for which I could not find anything useful. Maybe Im the first person thinking of doing it this way:
Approach: Database First
Database: SQL Server 2008 R2
Project : DLL (Data Access)
I have a data access library which encapsulates all the access to database as well as the biz functionality. The database has many tables and all the tables have the following 2 columns:
last_updated_on: smalldatetime
last_updated_by: nvarchar(50)
The project contains several models (or edmx files) which contain only related entities which are mapped to the tables they represent. Since each of the table contain the columns for last_updated_* I created a complex type in one of the models that is as follows:
Complex Type: History
By (string: last_updated_by)
On (DateTime: last_updated_on)
The problem is that it can only be used in the model in which I defined it.
A) If I try to use it in other model it does not show it in the designer
B) If i define it in the other models I get error History already defined
Is there any solution so that the History complex type, defined in one model can be reused by other models?
I was trying to do almost the exact same thing (my DB fields are "created", "creatorId", "modified", and "modifierId", wrapped up into a complex type RecordHistory) and ran into this question before finding an answer...
http://msdn.microsoft.com/en-us/data/jj680147#Mapping outlines the solution, but since it's fairly simple I'll cover the basics here too:
First create the complex type as you did (select the fields in the .edmx Designer, right click, select "Refactor into New Complex Type")
In the .edmx Designer (NOT the Model Browser) right click on another table/entity that has the same common columns and select Add -> Complex Property
The new property will be assigned a complex type automatically. If you have more than 1 complex type, edit the new property's properties and set the Type appropriately
Right-click on the table/entity again (in either the Model Browser or Designer) and select Table Mapping
Update the Value/Property column for each of your common fields (changing them, in my case, from "modified : DateTime" to "history.modified : DateTime")
Delete the old common fields from your entity, leaving just the complex type in their place