can I link myPartRecord to orchard userPartRecord?

Topics: Customizing Orchard, Writing modules
Feb 23, 2012 at 8:40 PM

I've greated a myPartRecord that persists in the orchard database. Can I link it to the orchard UserPartRecord so that when a user is created it also creates the MyPartRecord? Basically I want to just add more fields to the UserPartRecord but stored in myPartRecord. A one to one relationship. How would I go about doing this? Newbie here.

Coordinator
Feb 23, 2012 at 8:45 PM

It looks like you're just trying to add a new part to the User content type. Yes, you can do that. No need to create a relationship yourself, just let the system do it. Create a regular content part and add it to the type.

Feb 28, 2012 at 1:58 PM

You might want to look at the modules "Profile" and "Extended Registration" which will both surface any parts on the User content type. So Profile module gives your users a profile page / editor which renders any parts from User. And Extended Registration does the same but for the registration page.

Mar 8, 2012 at 9:42 PM

Ok, I have created the following file in my migration class:

    public class Migration : DataMigrationImpl
    {
        public int Create()
        {
            // SRB: Create an RSVPCode part entitity
            SchemaBuilder.CreateTable("RSVPCodePartRecord", table => table
                    .ContentPartRecord()
                    .Column<string>("FirstName", c => c.WithLength(50))
                    .Column<string>("LastName", c => c.WithLength(50))
                    .Column<string>("RsvpCode", c => c.WithLength(50))
                    .Column<string>("MappedPersonGuidString", c => c.WithLength(36))
                );

            ContentDefinitionManager.AlterTypeDefinition("User",
               cfg => cfg
                   .WithPart("RSVPCodePart"));
            
            return 1;
        }
    }

I reran my recipe and it did create the table. Now I thought that when I created a new user it would automatically generate a row
in RSVPCodePartRecord however this is not happening. What am I missing?
I also copied Register.cshtml into my view folder and added firstname,lastname and rsvp code prompts. This automatically overroad
the orchard register.cshtml which is really cool but now where to I put the logic to validate those new fields?

Developer
Mar 8, 2012 at 11:16 PM

Did you also create a ContentHandler that adds a StorageFilter for your RSVPCodePartRecord repository?

Mar 9, 2012 at 3:55 AM

yes:

    [UsedImplicitly]
    public class RSVPCodePartHandler : ContentHandler
    {
        private readonly IOrchardServices _orchardServices;

        private static readonly Object _syncLock = new Object();

        public RSVPCodePartHandler(IRepository<RSVPCodePartRecord> rsvpCodePartRepository,
            IOrchardServices orchardServices)
        {
            _orchardServices = orchardServices;
            Filters.Add(StorageFilter.For(rsvpCodePartRepository));

            OnLoaded<IUser>((context, user) =>
            {
                lock (_syncLock)
                {
                }
            });

            OnRemoved<IUser>((context, user) =>
            {
                lock (_syncLock)
                {
                }
            });
        }

    }

and here is my RSVPCodePartRecord:

    public sealed class RSVPCodePart : ContentPart<RSVPCodePartRecord>
    {

        [Required]
        public string FirstName
        {
            get { return Record.FirstName; }
            set { Record.FirstName = value; }
        }

        [Required]
        public string LastName
        {
            get { return Record.LastName; }
            set { Record.LastName = value; }
        }


        [Required]
        public string RsvpCode
        {
            get { return Record.RsvpCode; }
            set { Record.RsvpCode = value; }
        }

        public string MappedPersonGuidString
        {
            get { return Record.MappedPersonGuidString; }
            set { Record.MappedPersonGuidString = value; }
        }

    }

    public class RSVPCodePartRecord : ContentPartRecord
    {
        public virtual string FirstName { get; set; }
        public virtual string LastName { get; set; }
        public virtual string RsvpCode { get; set; }
        public virtual string MappedPersonGuidString { get; set; }
    }

Maybe because the fields are marked as required and there is no defaults?

Mar 9, 2012 at 7:14 PM

bump. Anyone? I don't have much hair left :)

Mar 9, 2012 at 7:45 PM

Use the Profile and itWorks.ExtendednRegistration modules from the gallery. 

Mar 9, 2012 at 8:27 PM
TheMonarch wrote:

Use the Profile and itWorks.ExtendednRegistration modules from the gallery. 


I tried that and it does work but why doesn't my code work?

Mar 9, 2012 at 10:02 PM

Ok, I got the the part to automatically create itself by adding the following to my handler:

            Filters.Add(new ActivatingFilter<RSVPCodePart>("User"));

Developer
Mar 9, 2012 at 11:44 PM
Edited Mar 9, 2012 at 11:45 PM

Oh yeah, that's right:

"The reason we included an ActivatingFilter for the Customer content type is that Orchard.Users does not come with a driver for the UserPart, so it does not automatically weld on any content type. Instead, Orchard.Users also uses the ActivatingFilter to weld the UserPart onto the User content type."

Now I'm not sure if this is exactly true, but it certainly looked that way when stepping through with the debugger.

Jul 1, 2012 at 11:57 AM
Edited Jul 1, 2012 at 12:09 PM

Hi, did it work in the end. I am doing exactly the same thing, but I can't get it to work. When I create a user, the user doesnt get created. Even updating an existing user doesnt work.

If it does work can you provide maybe the code listing? I think my Driver is not correctly set.

Jul 3, 2012 at 9:55 PM

@momoski - If you have a look at sfmskywalker's tutorial this gives a good code listing for creating users with your own part - I certainly found that all the info I needed was in here.