ruby-on-rails-7 encrypt polymorphic associations for certain type - encryption

How does one use the Declaration of Encrypted Attributes for Polymorphic Associations only for a certain type?
Using Active Record Validations like:
class Address < ApplicationRecord
encrypts :city, unless: -> { addressable_type == 'public' }
end
does not work.

Related

Creating custom GraphQL schema for Drupal 9 empty fields which are paragraph references

Have a decoupled Drupal 9 with Gatsby and a GraphQL. On Drupal's side there is a node called school there is a field (field_components) which is an Entity Reference Field which can have unlimited number of references to paragraphs. There are over 50 paragraph types on the site but that specific field only accept four (4) types. And I am trying to define their types in GraphQL.
exports.createSchemaCustomization = ({ actions }) => {
const { createTypes } = actions;
const typeDefs = `
type node__school implements Node {
field_location: String
field_type_r_a: Boolean
relationships: node__schoolRelationships
}
type node__schoolRelationships {
field_components: // this is where i need to define the 4 types
}
`
createTypes(typeDefs);
};
As you can see by the example above I've written out 90% of the necessary schema but I have no idea how to define the for paragraph types. I'm guessing that each individual paragraph would be called paragraph__machine_name (e.g. paragraph__carousel) but since there are four (4) of them I don't know how to chain them (define them all)
Any ideas?
From the GraphQL docs:
Unions and interfaces are abstract GraphQL types that enable a schema field to return one of multiple object types.
In action (using paragraph entities):
const typeDefs = `
type node__school implements Node {
field_location: String
field_type_r_a: Boolean
relationships: node__schoolRelationships
}
union fieldContentParagraphUnion =
paragraph__foo
| paragraph__bar
| paragraph__bat
type paragraph__foo implements Node {
field_1: String
}
type paragraph__bar implements Node {
field_2: String
}
type paragraph__bat implements Node {
field_3: String
}
type node__schoolRelationships {
field_components: [fieldContentParagraphUnion] #link(from: "field_components___NODE")
}
`
This official Gatsby plugin helped me tame my schema-related issues: gatsby-plugin-schema-snapshot
Saves a minimal schema to file, adds the #dontInfer directive to all top-level types, and re-creates the schema from the saved type definitions during bootstrap. Use this plugin if you intend to lock-down a project’s GraphQL schema.

How to query a property bag entity type in EFCore5?

In EFCore5, implicit tables are saved as Dictionary<TKey, object> sets, knows as Property Bag Entity Types. However, I cannot figure out how to create a LINQ query with a Where() clause that compiles for MySQL for such a property bag entity type.
For example, this code successfully retrieves the IQueryable reference to an intermediate table (generated by EFcore5's implicity many-to-many feature) given the ISkipNavigation:
ISkipNavigation nav = // some many-to-many relationship
IQueryable<Dictionary<string, object>> intermediateTable =
context.Set<Dictionary<string, object>>(nav.JoinEntityType.Name);
And this code successfully retrieves all the entries in the intermediate table:
List<Dictionary<string, object>> joins = await intermediateTable.ToListAsync();
In the resulting List, each Dictionary has just one key/value (representing the row).
However, I cannot figure out how to add a .Where() clause to the LINQ query which will compile:
joinTable.Where(d => d.Keys.First() == "foo").ToList();
joinTable.Where(d => d.Keys.Any(k => k == "foo")).ToList();
The error is:
Translation of member 'Keys' on entity type 'MachinePartMachineProfile (Dictionary<string, object>)' failed. This commonly occurs when the specified member is unmapped. Either rewrite the query in a form that can be translated, or switch to client evaluation explicitly by inserting a call to 'AsEnumerable', 'AsAsyncEnumerable', 'ToList', or 'ToListAsync'
I do not wish to do client-side parsing for performance reasons (the join table will be to big).
I note that the type reported by the error is MachinePartMachineProfile (Dictionary<string, object>). Some investigation showed that these types are being generated based upon the static Model.DefaultPropertyBagType (which is a Dictionary<string, object>). But despite staring at the EFCore code base, I cannot discern how to correctly query such a default property bag type.
I am using MySQL as my database, if it is relevant.
You can index the dictionary directly, with knowledge of the column name.
Working example would be:
joinTable.Where(d => d[columnName] == "foo").ToList();
And for the sake of completeness, if you have an ISkipNavigation instance, you can infer these keys as follows:
string foreignKey = nav.ForeignKey.Properties.First().GetColumnBaseName();
string localKey = nav.Inverse.ForeignKey.Properties.First().GetColumnBaseName();

Objects with multiple key columns in realm.io

I am writing an app using the Realm.io database that will pull data from another, server database. The server database has some tables whose primary keys are composed of more than one field. Right now I can't find a way to specify a multiple column key in realm, since the primaryKey() function only returns a String optional.
This one works:
//index
override static func primaryKey() ->String?
{
return "login"
}
But what I would need looks like this:
//index
override static func primaryKey() ->[String]?
{
return ["key_column1","key_column2"]
}
I can't find anything on the docs on how to do this.
Supplying multiple properties as the primary key isn't possible in Realm. At the moment, you can only specify one.
Could you potentially use the information in those two columns to create a single unique value that you could use instead?
It's not natively supported but there is a decent workaround. You can add another property that holds the compound key and make that property the primary key.
Check out this conversation on github for more details https://github.com/realm/realm-cocoa/issues/1192
You can do this, conceptually, by using hash method drived from two or more fields.
Let's assume that these two fields 'name' and 'lastname' are used as multiple primary keys. Here is a sample pseudo code:
StudentSchema = {
name: 'student',
primaryKey: 'pk',
properties: {
pk: 'string',
name: 'string',
lastname: 'string',
schoolno: 'int'
}
};
...
...
// Create a hash string drived from related fields. Before creating hash combine the fields in order.
myname="Uranus";
mylastname="SUN";
myschoolno=345;
hash_pk = Hash( Concat(myname, mylastname ) ); /* Hash(myname + mylastname) */
// Create a student object
realm.create('student',{pk:hash_pk,name:myname,lastname:mylastname,schoolno: myschoolno});
If ObjectId is necessary then goto Convert string to ObjectID in MongoDB

Entity Framework: Mapping Existing Tables w/ no Referential Integrity

In this scenario, I have an existing database with three models:
Address, which has a 'AddressId', 'ParentId', 'City', 'State', etc
Person, which has a 'PersonId', 'Name', etc.
Company, which has a 'CompanyId', 'Name', etc.
Because Address can contain rows for more models than just one table, there's no foreign key; the Address column 'ParentId' would contain either a 'PersonId' or 'CompanyId'.
To generate my DbContext, I used Entity Framework Power Tools Beta 2. Due to the lack of referential integrity, the classes it generated for Person and Company do not contain a collection of addresses like they should.
How would I go about altering those classes to add in this "Addresses" property, and ensure it's mapped to the Address table correctly?
At the moment I'm doing something like this; I'd rather have the context map it if possible:
public IEnumerable<Address> Addresses
{
get
{
IEnumerable<Address> addresses = null;
using(MyDb db = new MyDb())
{
addresses = db.Addresses.Where(a => a.ParentId == this.PersonId)
}
return addresses;
}
}
Thanks!
If you can, you should add an unique id to the Address table and then store that id with the entity that it belongs to, whether it be a person, company, vendor etc.
If you can't because of the multiple address scenario, then you could create a new table AddressXRef table that stores the GUID's of the entities (vendor, person, company etc), and the GUID of the address; so every entity could have multiple address and EF will be quite happy with this setup as there will be keys all around.
(I'd also want some sort of address type indicator on the Xref table so I knew what kind of address it was, mailing, shipping, etc)
Create partial classes for both Company and Person which have that property you have created in it.
public partial class Company
{
public IEnumerable<Address> Addresses { ... }
}

Different RavenDB collections with documents of same type

In RavenDB I can store objects of type Products and Categories and they will automatically be located in different collections. This is fine.
But what if I have 2 logically completely different types of products but they use the same class? Or instead of 2 I could have a generic number of different types of products. Would it then be possible to tell Raven to split the product documents up in collections, lets say based on a string property available on the Product class?
Thankyou in advance.
EDIT:
I Have created and registered the following StoreListener that changes the collection for the documents to be stored on runtime. This results in the documents correctly being stored in different collections and thus making a nice, logically grouping of the documents.
public class DynamicCollectionDefinerStoreListener : IDocumentStoreListener
{
public bool BeforeStore(string key, object entityInstance, RavenJObject metadata)
{
var entity = entityInstance as EntityData;
if(entity == null)
throw new Exception("Cannot handle object of type " + EntityInstance.GetType());
metadata["Raven-Entity-Name"] = RavenJToken.FromObject(entity.TypeId);
return true;
}
public void AfterStore(string key, object entityInstance, RavenJObject metadata)
{
}
}
However, it seems I have to adjust my queries too in order to be able to get the objects back. My typical query of mine used to look like this:
session => session.Query<EntityData>().Where(e => e.TypeId == typeId)
With the 'typeId' being the name of the new raven collections (and the name of the entity type saved as a seperate field on the EntityData-object too).
How would I go about quering back my objects? I can't find the spot where I can define my collection at runtime prioring to executing my query.
Do I have to execute some raw lucene queries? Or can I maybe implement a query listener?
EDIT:
I found a way of storing, querying and deleting objects using dynamically defined collections, but I'm not sure this is the right way to do it:
Document store listener:
(I use the class defined above)
Method resolving index names:
private string GetIndexName(string typeId)
{
return "dynamic/" + typeId;
}
Store/Query/Delete:
// Storing
session.Store(entity);
// Query
var someResults = session.Query<EntityData>(GetIndexName(entity.TypeId)).Where(e => e.EntityId == entity.EntityId)
var someMoreResults = session.Advanced.LuceneQuery<EntityData>(GetIndexName(entityTypeId)).Where("TypeId:Colors AND Range.Basic.ColorCode:Yellow)
// Deleting
var loadedEntity = session.Query<EntityData>(GetIndexName(entity.TypeId)).Where(e =>
e.EntityId == entity.EntityId).SingleOrDefault();
if (loadedEntity != null)
{
session.Delete<EntityData>(loadedEntity);
}
I have the feeling its getting a little dirty, but is this the way to store/query/delete when specifying the collection names runtime? Or do I trap myself this way?
Stephan,
You can provide the logic for deciding on the collection name using:
store.Conventions.FindTypeTagName
This is handled statically, using the generic type.
If you want to make that decision at runtime, you can provide it using a DocumentStoreListner

Resources