I am a student developer with Oregon State University's Business Solutions Group and I am currently working on a Salesforce integration project for one of the University's colleges. As you can imagine, the data we are working with is coming from several different places and in a variety of different formats. I was wondering if anyone with more experience in setting up Salesforce object schemas could talk about the pros and cons of relational database style normalization in Salesforce. What do we gain by not normalizing and using Record Types to categorize data? (For example: a Person-Account that encompasses Students and Faculty and uses Salesforce Record Types to differentiate between the two) What do we lose?
This message was inspired by this webpage:
Salesforce Guru: Record Types
Notice that the first thing it advises is to not normalize (overmuch) because it prevents us from taking advantage of some built-in Salesforce functionality. Overall, the page seemed helpful, albeit incomplete.
The answer to this question seems critical to the success of our project and will help us to decide how to reorganize the data we are initially migrating to Salesforce and ultimately build our Salesforce object schema, so any thoughts, additional resources or advice are very much appreciated. Thanks!
The inspirational web page is correct. With the "standard objects" like Account, Contact, Case, Lead, etc. and even with custom objects the system works best to use fewer tables (objects) and segregate the data based on some value (such as record type).
By using record types you leverage the point-and-click UI. For example, for the Account object you have a default page layout. But for each record type you can have a unique page layout. Furthermore the security model uses record types to limit or grant access as appropriate to different user profiles.
As the author says SOQL is NOT SQL.
Related
As a newbie to Liferay I am investigating whether I used the right approach to populate data forms.
When populating a form with a number of text fields using an external REST service, I alraedy implemented the following approaches:
Creating a web content page and fill it with Ajax. Works, but using Jquery is not my preferred (modern) approach for accessing REST services.
Creating a web page using an Angular/React portlet, etc. Also worked for me. As I understand, per page I have to create a small Angular (module) project.
Creating a Form page that retrieves the fields by a data provider. Worked also for me, but this was presentation only.
"Service builders" are used in the examples for working with databases. I did not use this method yet.
Below are a few questions but there only 1 theme: when using Liferay, what are the beste techniques to populate data forms?
Is there a better/easier approach in Liferay to fill the form?
When using option 3, will it call the data provider multiple times for each field?
What if I would like to post the populated form data to the REST service?
Which approach is best to fill a table with rows of data?
Can/should "service builders" be used for interacting with REST services as well?
Is there a way to interact with basic components and Angular? I could not find anything on the internet yet.
I believe that your question is still out of focus for stackoverflow, as it's asking for "the best" way - to that, the answer is a firm "it depends".
You're listing a couple of options yourself. What you choose will in the end depend on
the technology you know
the technology you feel comfortable maintaining long term
the business requirements - e.g. how flexible to you need to be? can you go low-code, or do you need the full flexibility to develop an actual app
how frontend-heavy are your requirements
how independent of Liferay do you want them to be?
That being said: All of your options are good choices in various situations that you need to solve.
My general recommendation is to think maintenance, and optimize for the future maintenance of your solution, rather than the initial implementation time.
But, unfortunately, no firm single answer.
I am still a relative newcomer to Expression Engine as a developer and a user. I am faced with the problem that a lot of my knowledge is being passed to me by users who have found ways to accomplish tasks traditionally undertaken by developers (eg product libraries) by using the channels system.
What I wondered was what people's views are on when it is best to advise a client to use this and when not to.
Let me use an example, a client wants a system which had venues where events could take place. The previous developer had chosen to use the membership system for the venues and the channels system for the events and write some custom code to attempt to knit the two together, specifically because there are not enough hooks to accomplish some background automated tasks like looking up the long/lat of the address of a venue when it is created or updated.
I am picking up after someone else's work largely but its not their fault, it was the information they were given as they were also new to the system.
In any other project this would be a master-detail type setup, events belong to venues, i'd probably write 2 custom tables, editors in the admin area via modules and then use regular custom code in the pages to display and act upon the info - this way, I could control what's happening when a user hits submit.
However, the instigating party is a veteran user of Expression Engine and instructed the previous developer in the manner of "oh, just put it all in the channels and then there's this tag and that tag and so on".
So, am I missing the point or am I right that this does not fit the channels system and when should you use channels and when not?
Thanks friends.
This question is very hypothetical and every developer will give you a different answer as it all depends on the requirement and how that EE developer rolls.
Fundamentally ExpressionEngine allows you to approach builds in many ways, none are right and wrong, albeit some are easier, some harder, others just plain daft.
Basically Channels are groups of data "entries" - these can be anything. Using your example, venues could be one channel with fields created relevant to the subject (e.g. location, size, price, etc). And another channel for events with different fields (e.g. date, type, location).
Mostly anything can be slotted into a channel. But member details are best held within the native member functionality (although there is a commercial add-on that holds member data in a channel).
You reference the previous developers approach - this could be because they used a third-party add-on that required the data to be held separately to channels, or a lack of understanding on best approach. Or just because the developer decided to approach it that way! I suspect the last developer then associated a member (venue) to an entry (event) to link the event to the venue. Basic EE functionality allows for related entries which allows you to associate 1 entry with another (e.g. Event -> Venue), or using the excellent Playa add-on, so this approach is really not necessary.
Personally I would always store the data in channels, and people/members in the native membership functionality (e.g. admin, visitors to the site, customers, etc). I'd only build an add-on (utilising it's own tables/data) to store additional information if it was way outside what EE could store.
To answer your practical question (it's stretching the scope of what Stack Overflow questions are supposed be honestly): you should use a channel for Venues and channel for Events, and the Venue field in the Event entry is a "Related Entries" fieldtype linked to the Venues channel. That's the "standard" EE way, and the most similar to a traditional database schema.
Entity has a custom field based on which, some security roles should have access to records of that type and some should not.
Javascript can be used to close form after checking roles. But I'm looking for back end solution that will disabled access to this records in workflows and searches too.
For example, product should viewable by everyone if manufacturer is our company and only by Competitor Products Specialist if other.
You might be able to write a plugin that would automatically share the record with the appropriate Users/Teams. When somebody updates that field, the plugin would run and share/unshare the record according to your business logic.
Disclaimer: I haven't actually tried this before, and there may be performance issues if you have lots of records (and therefore lots of sharing records).
I ended up writing the plugin that works on pre-Retrieve event and modifies retrieve query by adding additinal filter by field.
Pardon the length here...hopefully I didn't go overboard...
I'm in the process of working on my first production MVC application and I'm trying to stick to DDD principles in the process. I've run into some questions related to how to deal with the security requirements of the application and thought I'd see if the SO community could offer some best-practice suggestions.
Domain Information
To use a simplified explanation, this application will have AffiliateCompanies, Users, and Customers.
AffiliateCompanies are hierarchal, so one affiliate can sign up and be tied to the activities of another affiliate. The root is the main company providing the products/services.
Users all belong to an Affiliate entity.
Customers are organizations to which the products/services are sold. Affiliates are assigned to customers such that it is possible for two hierarchically-unrelated affiliates to split a Customer.
Security Information
Rights to perform certain actions in the application will be determined based on an ACL-type of arrangement. Each User object has a property that is a collection of SystemAccessRules that determine what actions they can perform and what the scope of their permissions are (their own objects, their affiliate's objects, or their entire hierarchy's objects). Users can also belong to roles, which themselves have that same collection of SystemAccessRules.
As a result, if a user logs in and wants to see a list of "their" customers, the list could be comprised of customers they are individually assigned to, customers anyone in their affiliate organization is assigned to, or customers anyone in their organization or any of their child affiliate organizations are assigned to.
Database Considerations
DDD aside, at some point the storage strategy has to come into play. In this simple scenario, the tables align with the objects above (including a roles table), with a few support tables to support the relationships between the objects:
AffiliateCustomers - this table allows for a many-to-many relationship between affiliates and customers by storing the PK of each entity as a pair of FKs that are themselves a composite PK for this table.
ACL - this table stores the security information, specifically the subject of the entry (either a user or a role), the action in question (e.g. "CreateCustomer"), the permission (allow or deny), and a scope (their own stuff, their organization's, or their network's).
The Question...Finally
I'm using a combination of repositories and services. I'm trying to keep business logic in the services and out of the repositories or database, but due to the security design here, a simple request for the list of "their" customers could be immensely burdensome, especially as the data set grows. I was trying to use Linq where possible, but this architecture seems not to be very suited. As I see it, here are my choices:
Accept the requesting user as an argument for service methods (or determine it by context), and have the service method populate a list through multiple queries to Linq repository. This would require pulling the list of customers, then iterating through each customer to issue another query to pull the ACL data, then using that data to filter the first list based on permissions. The hierarchy issue would require some fancy Linq footwork (like this), if it's possible at all.
Even if the hierarchy issue could be made to work, it seems like this solution won't perform very well...
Accept the requesting user as an argument, but pass it and the required permission (e.g. "View Customers") to the repository in order to retrieve appropriate data from the database through a stored procedure that would use several EXISTS clauses in a CTE query that could account for the hierarchical nature of the data and the need to check for role and user security.
This pushes a fair amount of logic to the database, which seems very anti-DDD and generally bad.
I'm leaning more toward the second option, but that may be because in my past projects that's how I've done it. I'm not even sure if my design overall is on the right track (in the past the permission declarations were done using bit flags, so it was even easier to do the DB query using bitwise operator).
Has anyone been in similar situations, and if so can you comment on the performance and maintainability of the solution you pursued? I want to stick to high-minded programming principles, but not at the expense of simplicity and common sense.
Have you considered using the specification pattern to pass your business rules down to your data access layer?
The service constructs a specification tree which it passes to the repository. The repository converts the specification into an Expression<Func<Customer, bool>> which it passes to IQueryable<Customer>.Where(...). When the repository materialises the collection, e.g. by calling ToList(), the business rules are translated into SQL and executed on the database server.
Last time I checked, LINQ to SQL didn't support CTEs, so you may need to use a view to flatten the hierarchy.
My workplace will be starting to use Sharepoint internally during the coming months. I'm pretty excited about the possibilities of having more structured data on our intranet. A key part of this is allowing related data to be spread across the site hierarchy.
I'm currently experimenting with a list of Committee Members, with the idea that somewhere on the site you could see a list of everyone on every committee. Then in other parts of the site, you only want to see members of a single committee. From the various articles and blog posts I've been reading, it seems like there are three accepting ways to approach this:
Roll Up - Subsites have their own lists (optionally from a list template). Content types are used so the instances can be collected into a Data View Web Part on the parent site.
Pull Down - A master list is defined in the parent and each subsite contains a view of that list, filtered
Purchase or create a custom rollup webpart.
What are your experiences in different situations? What are the tradeoffs of these techniques and are there other (good) ways I've missed?
BTW, the committee members example is what I'm currently experimenting with to try out different possibilities. I'm more interested in the general tradeoffs, not necessarily specific to this example.
Having done this a number of times on different sites, for your situation, I recommend:
1.Roll Up - Subsites have their own lists (optionally from a list
template). Content types are used so
the instances can be collected into a
Data View Web Part on the parent site.
This gives more flexibility, not only can other sites in your site collection get this information, you can use the search query webpart to roll up the information in other site collections (the CQWP and DVWP do not work across site collections).
The only time I have used a Pull Down model is when there logically is only one list that I site collection will go to. Such lists for us have always been functional in nature, e.g. A list of content query definitions for a some custom functionality or a list of customers that ALL sites rely on and is used to populate an installed custom field control.
I would say that both will work equally well but the advantages of one over the other really come down to whats more convinent for how you'll have your intranet site collection structured.
You might also want to consider using the Content Query Web Part (CQWP) in combination with a complimentar site collection structure so that you can surface the committee member data.
With a little customization, the CQWP can do some amazing things - and it has been fully optimized under the hood by the product group team for managing all kinds of queries. It's easy to configure and use, and there are plenty of examples on how to use them on the web.