i have a simple iphone project which contains a simple xcdatamodel that has a single entity
with roughly 3 attributes..
i want to know if there is a way to programmatically add an attribute to an entity..
i.e. if the user presses an "add" button of some kind, a simple string attribute is added to the entity and saved..
If this is not possible could someone point me in the right direction..
You can programmatically alter entities but you can't alter a managed object model after it has been assigned to a managed object context so that makes it useless for any user defined alterations. In any case, you wouldn't want to add entities programmatically because that would make your previously created persistent store file useless.
If you want to create a more free-form , user extensible data model, you have to back out and make your entities more flexible by adding an optional relationship to another entity or entity inheritance group that can model additional data.
For example: Suppose you have a contact list and you want to add free form fields to each contact. You would set up your entities like this.
Contact{
name:string
phone:string
userDefinedFields<-->>UserDefined.contact
}
UserDefined{
name:string
contact<<-->Contact.userDefinedFields
}
Whenever the user adds a new field, you create a new UserDefined object and add it the Contact.userDefinedFeilds relationship. You can flesh that out as needed. If you need more than one type of user defined field you should set it up like this:
Contact{
name:string
phone:string
userDefinedFields<-->>UserDefined.contact
}
UserDefined{
name:string
contact<<-->Contact.userDefinedFields
}
TextField:UserDefined{
text:string
}
NumberField:UserDefined{
numValue:Number
}
You can then drop in a TextField or NumberField object into the Contact.userDefinedFields as needed.
i am not so sure if you can add an attribute with code, but maybe you can consider using one to many relationship?
Related
I have a new requirement to add a custom field called document number in the item form which should be editable.
We should use the following steps to create a custom fields.
Creating a user class - The user class definition is the highest level to extend an application database table.
Creating user fields - User fields are generic and can be a part of many classes. If the user changes any property of a user field, all user classes inherit the change.
Associating the user field with a user class - The UET tools look for this association to place the user fields in the form that belongs to the user class.
Linking an application database table with the user class - The association between a table and a class provides the information that UET needs to retrieve, arrange, and display the user fields that belong to a user class. To link the table with the class, define a rule that determines if the record accessed has a valid user class associated with it. If valid data is entered in existing fields to make the rule expression true, the new user field displays.
Impacting the schema - Use the UET Impact Schema form to apply the changes you made in the previous steps to all affected databases.
Overview:
I have an iOS app that uses CoreData
There is an entity called Animal
It has a set of records Lion, Tiger and Elephant
I would like to mark only one of the records as favourite.
Similar entities with the same approach:
Similarly I could have other entities such as Car, Bike.
Each entity would have a set of records.
Again each entity should only have one favourite record
Reason:
App has an option to create a new document
When the new document is created, it would be populated with default values for each entity (by selecting the favourite record of each entity)
Note: Only one record can be marked as favourite at a given time
Possible models I thought of:
1. Field called isFavourite
Create a field in Animal called isFavourite.
Mark only one of the rows as isFavourite as true.
Much of the logic to maintain isFavourite is managed in code.
2. Separate entity called Favourite
Create a separate table called Favourite and have a dummy row in it.
Establish a relationship from Favourite to Animal called animal.
This will point to the favourite record.
Questions:
What is the preferred approach to tackle this problem ?
Are there any other alternatives ?
Go with option 2, maybe call it Config. If you want to ensure it is just a singleton add a attribute that is unique and can only be zero.
You can write a helper computed var returning true if the reverse relationship is non-nil.
Main advantage of option 2 is the simplicity of changing the favourite, you don't have to scan through all the items to to set them non-favourite just change it on the singleton config.
Give some thought to other parts of the app and to what you might want to do in the future.
Adding a field: Works OK but requires some code to maintain, which might be error prone. On the other hand maybe one day the app might allow multiple favorites, and this will just work with that.
Using a separate entity: Also works OK but adds a whole new entity where you'll only have a single instance. In general, if you have an entity where you only ever want one instance, you're doing it wrong. On the other hand this also works well with the potential for multiple favorites.
A third approach is to save the objectID for the favorite animal somewhere outside of Core Data, like UserDefaults. Save it, and then find the favorite by using NSManagedObjectContext's existingObject(with:) method. You can't save the NSManagedObjectID directly but you can get its uriRepresentation() and save that.
I'd probably go with #1 in most cases but it depends what else I need in the app.
I have two models with a foreign key relationship between them. In the admin, the edit page for the model with the foreign key relationship described (Model No. 1) displays a ModelChoiceField. The page for the other side of the relationship (Model No. 2) displayed nothing, until I added the first model to the ModelAdmin as an inline. The inline gives me the option of creating a new object from Model No. 1.
I want to add a ModelChoiceField to the inline on Model No. 2 so that users can choose between creating a new object or selecting from a list of pre-existing ones.
Ideally, I would also be able to use a filter to populate the new ModelChoiceField for Model No. 1 objects.
Okay, asking this question got me nothing but the cool tumbleweed badge for my profile. I eventually discovered the following solution. It's simpler than I expected but it left me asking another question here because, once implemented, selecting from the ModelChoiceField on the admin page and saving does not create the foreign key relationship as expected.
Anyway, on the the solution:
My Art model contains the boolean field "has_storypak" to indicate whether it has a relationship to and instance of the Storypak model. Since I expected Art instances to only related to one Storypak while Storypaks could have many associated artworks, I wrote the following custom field to only contain instances for which the value for "has_storypak" was False.
class RuntimeArtSelectForm(forms.ModelForm):
storypak_orphan = forms.ModelChoiceField(label="Art",
queryset=Art.objects.filter(has_storypak=False))
class Meta:
model = Art
fields = ('storypak_orphan',)
Next I added this form to an inline form for the Art model...
class ArtInline(admin.TabularInline):
model = Art
form = RuntimeArtSelectForm
... and included the ArtInline in the ModelAdmin for Storypak. This gave me the drop-down containing the filtered list of model objects I was looking for. However I still have the problem mentioned above and this open question looking for a solution.
I want to create a commenting model with a twist. I want there to be multiple commenting columns like on hunch.com, except that a user can decide how many columns there should be. Also, a user can decide the title for each column.
This is rather dynamic, so how would I set up my tables for this?
Seems like a perfect use case for NoSQL. I'd use something like CouchDB or Mongo here. Since there you don't have a schema you can add the attributes as needed.
Since you cannot really change the attributes of a model, if you want to create dynamic model attributes, you can have 3 models :
User
Attribute
UserAttribute
Now, you can add as many attributes are you want (Attribute is the static representation of an attribute). Then, a user can have many attributes through user_attributes.
I have asp.net membership and I use the built in Create user method since it is convenient now after this depending on the user I want to add 2 more fields to the aspnet_UserTable.
In my aspnet_user Table I have like this
// All Standard Fields that come with this table
ClubID<nullable)
ClubName <nullable)
I have a table that relates this
Club Table
ClubID<PK>
ClubName
So this relationship forms that one club can have many users. But one user can only have 1 club.
So now I been trying to figure out how to add the ClubID to the aspnet Usertable since it does not show up in the Entity Framework Diagram since it does not show FK.
// Note in this case I am just using EF made to create but in reality I will use the Membership.Create.
aspnet_Users test = aspnet_Users.Createaspnet_Users(Guid.NewGuid(), Guid.NewGuid(), "myTest5", "mytest5", false, DateTime.Now);
test.Club = Club.CreateClub("One224", "Two224");
test.ClubName = "go";
MyEntities.AddToaspnet_Users(test);
MyrEntities.SaveChanges();
So what I have works but it just makes no sense and I hope there is a better way. Like I try to create the club and then stick it in the test.club.
This add's the ClubID primary key but does not add the clubName.
So then I have to add the club name separately. Like why? Is there not a better way?
I also prefer linq method syntax so if it is needed and you know this syntax can you please write it in that.
I would recommend a few things.
One: Strongly consider not adding columns to the aspnet_* tables. If you ever want to change your authentication method down the road you'll be stuck lugging those tables around with you even though you won't need them anymore. Also, there may be a new, better version of the membership provider one day that you won't be able to upgrade because you have customized the membership schema.
Two: Instead, why not create a new table called User (or something of your liking) that has your own primary key but links back to the ASP.NET Membership unique key (the guid).
Your table might look like
User
UserId (PK)
AuthenticationUserId (FK back to aspnet_User table)
ClubId (FK back to your club table)
Three: I don't understand why you've repeated ClubName both in your user table and in your Club table. You really only need to define the ClubName once, right? Keep your Club table how it is but remove the ClubName column from the user table.
Your code above for associating the club with the user is correct and works because that's how the Entity Framework works. You're associating entities with each other and are abstracted from some of the relational aspects of your data schema. It's a little strange to get used to it first but it does work.