Paper trail association - paper-trail-gem

the object of my model has an association key and when the field with the key changes in the history, it is shown that the key of my object has changed, and I need to display not the key itself, but for example, the 'name' field of the object associated with the key, is it possible to do this?

I see two options:
you can add a name column to your versions table (https://github.com/paper-trail-gem/paper_trail#4c-storing-metadata)
you can use the https://github.com/westonganger/paper_trail-association_tracking (https://github.com/paper-trail-gem/paper_trail#4b-associations) which is currently compatible with PT < 12 (https://github.com/westonganger/paper_trail-association_tracking/issues/27)

Related

Add references to a chosen column different from id

Is it possible to add references to a column different from the id column?
Usually when a relationship between two models (Model1 and Model2) is created, the use of model1:references and model2:references for the creation of the Relationship model automatically adds a model1_id and model2_id column (along with an index and a foreign key reference) for use in the model1/model2 association:
rails generate Relationship model1:references model2:references
Say for instance Model1 = Teacher and Model2 = Pupil.
Suppose that Model2's records (pupils' records) are updated every now and then with a rake task: the values of its attributes (for instance name and school_credits) would change, preserving id and ranking (1 to 100).
Associate a teacher with a pupil_id would not have much sense.
Each teacher should be instead associated with his/her pupils' names using as a foreign key reference the attribute pupil.name instead of pupil.id.
Is that possible?
What options can I add to the command rails generate Relationship or what reference am I supposed to add to have this result?
Yes, you can. Check sections on foreign_key and primary_key from the following link. I don't use generator so I cannot comment on which options to pass into generator, but you just need to ensure that the column to be used as foreign key exists in your table and that you assign appropriate foreign_key in the model files.
But why do you need it? I don't understand what kind of use case you might have that would require you to keep id and ranking identical.

If we need to use a custom ID in Rails, should we use FriendlyID or Primary Key?

I need to create a product code which will be generated with a custom function. It will start with a letter, have the id of the category and then have a random 7 digit number. For this, I can set the primary_key to a string and generate the code or I can use FriendlyID. What might be the best for this situation?
Short answer: Use something like friendly_id
The story now:
Choosing a natural key for the primary_key of a table should always be measured well, it has an impact on your data model.
The first issue is regarding related records in other tables. If you will have related tables, the foreign key in those tables should also be VARCHAR and match your generated primary key. If you are not sure what to do, avoid custom primary keys.
Another issue in your question may be:
It will start with a letter, have the id of the category
Is this id the primary key of a Category model? If it's the case, you are generating a key with DB isolation in mind, but re-tighting with this one. Think again for this one.
Go for a slug generated by your function, you will be free for the future. You may create a brand new algorithm and thus only do a once for all change of the slugs. You may even have 2 slugs, the old one which redirects to the new one, and the new one.

Active Record: Implicit value for part of multi column belongs_to key

We have multiple lists of shops from different data sources that have to be matched.
The shops have a composite primary key [source, id]. The matching creates a separate entry in the shops table with source=0 and extracts values (name, url, ...) that can differ a bit from source to source.
Now I could add another two columns meta_shop_source and meta_shop_id to shops and a belongs_to :meta_shop, class_name "Shop", foreign_key: [:meta_shop_source, :meta_shop_id] to the Shop model. I am using the composite_primary_keys gem.
However, as meta_shop_source is always 0, it would seem like a waste of space. The same process will later on be used for products and there are millions of rows, so optimization will be needed.
So I am looking for something like belongs_to :meta_shop, class_name "Shop", foreign_key: [0, :meta_shop_id] or a method that I can override so that I don't need the meta_shop_source column in my database.
The one alternative is to define the value in the model so that you can directly access it from the controller directly.
But yes for undefined columns in tables, attr_accessor can be used as you don't want to store in the database directly and that will only exist for the life of the object.
attr_accessor :source
If the meta_shop_source will always be 0, then there is no need to create a column with this field in the table.
Just use a foreign primary key, meta_shop_id.
Similarly, the primary key for the Shop should be id.
Having so, you will never have to worry about the source as it will be 0 always.
You can define the value in the model so that you can directly access it.
UPDATE:
As far as optimization is concerned then do it at migration level by adding indexes with:
add_index wherever necessary. Eliminating one column just because of one source having 0 is not a good idea and will not effect the performance. This may be possible if all of the sources also have values greater than 0.
Since you have a distinct “source” field, an index can be created. By creating an Index, you would be basically creating an internal register which gets saved in by the MySQL itself.
ALTER TABLE shop ADD INDEX (source);
Upon creation and setting of the Index, later whenever you wish to fetch some information pertaining to the individual who has been assigned the source 5, the service would straight-way go to it by using the index, hence generate a result at a much faster pace than the earlier query.

What's the _type column for a polymorphic used for?

From the Rails Guide, to establish a polymorphic relationship on one model, I need to add two columns for the corresponding table.
As the image below shows, the _id column is used as a foreign key. But I cannot figure out the usage of the _type column? What's the usage of it?
The _type column is used to identify what resource this comes from. In this case, the polymorphic resource could be one of Employee or a Product. In other words: an image can relate to either a product or an employee.
The _type column will simply contain the string of either "Employee" or "Product". When this association is accessed, Rails will use it to know what model to use to load the associated object.

EF4: Creating a 0..1 to Many Association

I am trying to add an association that I didn't have originally. I realized that two tables were technically related, and that some navigation properties might simplify what I would have otherwise had to do manually. The tables and their keys look like this:
Import
Primary Key:
Number : Int32
Date : DateTime
Hour
Primary Key:
DepartmentID : Int32
UserNumber : Int32
Date : DateTime
The association is named ImportHour. Import.Number maps to Hour.UserNumber, and Import.Date maps to Hour.Date. I am trying to add an association that is 0..1 on Import, and * on Hour with navigation properties and no additional foreign keys. When I do this, the designer tells me that the association is not mapped. If I then generate the DDL, it creates new fields Hours.Import_Date and Hours.Import_Number (Hours is the actual database table name for the Hour entity). If I manually map the fields, I end up with the following error:
Error 3021: Problem in mapping fragments starting at line 332:
Each of the following columns in table Hours is mapped to multiple conceptual side properties:
Hours.Date is mapped to <ImportHour.Hour.Date, ImportHour.Import.Date>
Hours.UserNumber is mapped to <ImportHour.Hour.UserNumber, ImportHour.Import.Number>*
I am not really sure what is happening, and I don't think I understand the 'mapping' process well enough to figure this out. It almost seems as if it wants a quintuple key, instead of realizing that the one key maps to the other. I look at my other one-to-many associations, and they do not even have table mappings; I think they have referential constraints instead, but you obviously can't have a referential constraint with a 0..1 to many association.
There are two ways to define relation but in your case you must use the Foreign key association. It means that once you draw association in entity model you must select it and define referential constraints.
You cannot have 0..1 on Import because in such case UserNumber and Date in Hour must be nullable. That is what that relation mean. If no principal entity exists (Import) FK properties in dependent entity (Hour) will be null.
Btw. using DateTime in primary key is not recommended.
As far as I can tell from other databases I have since used, the issue here seems to be that the EF model requires a foreign key to already exist in the database. While I cannot seem to get EF to generate one, it will accept one if it already exists. (Contrary to what I said in the question, you can have a referential constraint on a 0..1 to many (nullable) foreign key).
#Sahuagin this may be long after your question but did you try after adding the association, deleting the scalar property in the designer -- example after creating the ImportHour association, delete the hour.usernumber and hour.date from your hour entity.
this way the independent association established this way is the only relationship between yuor entities - thats the meaning of independent association

Resources