In model rules i have custom rule:
array('source_id, postcode, state, fname, lname, email, address, city, birthday, gender, ip, phone,validation', 'validateCustom', 'on'=>'spam,normal'),
The problem is, that this rule executes 12 times (number of attributes -1).
public function validateCustom()
{
//here all validations done
}
How to prevent it? I want to validate all this params 1 time and not x. Thank you for any help.
I have an idea:
class YourModel extends ActiveRecord
{
public $ranValidate = false;
.......
public function validateCustom($attribute, $params)
{
if($this->ranValidate == false) {
//Implement your code
$this->ranValidate = true;
}
}
}
Related
How to handle unknown parameters in ASP.NET Core? When I use [FromQuery] it just ignores the unknown parameters, but ideally it should return 400 if the parameter is unknown so the caller knows it needs to fix the parameters?
Example: GetRecords tries to use any StartDate or EndDate from query string, use default value if they are not specified.
But if a query like ?StartTime=2021/2/15&EndTime=2021/2/16, the code actually will return all records from DB as it treats like no parameters passed. Ideally it should throw an error to let caller know the parameter names are invalid.
class RecordQuery
{
public RecordQuery()
{
StartDate = DateTime.MinValue;
EndDateTime = DateTime.Now;
}
//...
}
class Controller
{
public async Task<ActionResult<RecordsResult>> GetRecords([FromQuery] RecordQuery query)
{
// query db where date < query.EndDateTime && date > query.StartDateTime;
}
}
When I use [FromQuery] it just ignores the unknown parameters
Actually, this is the default behavior of the querystring parameters. But you could return an Invalid Request status, so that the client knows that what it's trying to do isn't valid.
To implement it, you can use the ActionFilter, get both the action parameters and request query string queryParameters and make a judgement. Codes like below:
public class QueryActionFilter<T> : IActionFilter
{
public void OnActionExecuted(ActionExecutedContext context)
{
}
public void OnActionExecuting(ActionExecutingContext context)
{
var model = context.ActionArguments.Values.OfType<T>().Single();
var modelProperties = model.GetType().GetProperties();
var queryParameters = context.HttpContext.Request.Query;
if (!queryParameters.Select(q => q.Key).All(queryParameter => modelProperties.Any(p => p.Name == queryParameter)))
{
context.Result = new BadRequestObjectResult("Querystring does not match");
}
}
}
Then in controller
[TypeFilter(typeof(QueryActionFilter<RecordQuery>))]
public async Task<ActionResult<RecordsResult>> GetRecords([FromQuery] RecordQuery query)
{
// query db where date < query.EndDateTime && date > query.StartDateTime;
}
You can see example https://learn.microsoft.com/en-us/aspnet/core/tutorials/first-web-api?view=aspnetcore-5.0&tabs=visual-studio#the-puttodoitem-method
if(StartDate == null){
return BadRequest();
}
Let's do the same thing with another input parameter(s) (query conditions)
If you want validate input parameter(s), use [Required] for model of [FromQuery], see https://stackoverflow.com/a/19279419/3728901 . In your case, it is model RecordQuery .
I'm trying to deploy Apex class from the sandbox to Production.
But I get a code coverage error.
My code coverage is 69% I don't know how to increase it to 75%. but my code works fine on the sandbox.
Please help me with it.
My code is:
#RestResource(urlMapping='/TestAPI')
global with sharing class TestingAPI {
#HttpPost
global static string doPost(string company, string first_name)
{
Lead objLead = new Lead();
objLead.Company = company;
objLead.FirstName = first_name;
insert objLead;
return 'Submitted Successfully';
}
}
Per this answer, the standard required fields on the Lead object are Company, LastName and Status, so I had to change your class slightly. I also moved the returned string to a constant to make it available in the test class as well.
#RestResource(urlMapping='/TestAPI')
global with sharing class TestingAPI {
public static final String SUCCESS_MSG = 'Submitted Successfully';
#HttpPost
global static string doPost(String company, String lastName) {
Lead objLead = new Lead();
objLead.Company = company;
objLead.LastName = lastName;
insert objLead;
return SUCCESS_MSG;
}
}
A test class for this could look something like the following (100% coverage):
#IsTest
public class TestingAPITest {
#IsTest
static void test_doPost() {
String company = 'Test Company';
String lastName = 'TestName';
String returnedStr = TestingAPI.doPost(company, lastName);
System.assertEquals(TestingAPI.SUCCESS_MSG, returnedStr);
Lead testLead = [
SELECT Company, LastName
FROM Lead
LIMIT 1
];
System.assertEquals(company, testLead.Company);
System.assertEquals(lastName, testLead.LastName);
}
}
A user has a sponsor:
public function sponsor()
{
return $this->belongsTo(User::class, 'sponsor_id');
}
A user has referrals:
public function referrals()
{
return $this->hasMany(User::class, 'sponsor_id');
}
A user is considered capped when they have 2 or more referrals:
public function activeReferrals()
{
return $this->referrals()->whereActive(true);
}
public function isCapped()
{
return $this->activeReferrals()->count() >= 2;
}
A user can give points. By default, the sponsor will receive them, but if the sponsor is capped, I want the points to go to a sponsor's referral that is NOT capped. If all the referrals are capped, then it does the same thing with the level below (the referral's referrals).
If I go user by user making database calls for each one, it's gonna take a long time. How can I write a scope that makes recursive calls until it finds the first active referral in the tree that's not capped?
This is what I'm trying to do:
Please give this a try... I believe this will work for you :)
public function scopeNotCappedActiveReferrals($query, $count) {
return $query->withCount(['referrals' => function($q) {
$q->where('active', true);
}])->where('referrals_count', '<', $count);
}
For the second part...
// Finally you can call it with
public function allReferrals() {
$users = User::notCappedActiveReferrals(2)->get();
$allUsers = $this->findNotCappedActiveReferralsRecurrsively($users);
}
// Do not place this function in the model,
// place it in your Controller or Service or Repo or blahblah...
// Also, not tested... but should work :)
protected function findNotCappedActiveReferralsRecurrsively($users) {
if(!count($user)) {
return $users;
}
foreach($users as $user) {
$moreUsers = $user->notCappedActiveReferrals(2)->get();
return $users->merge($this->findNotCappedActiveReferralsRecurrsively($moreUsers));
}
}
Hope this is what you need :)
I have a hierarchy of actors in Akka.Net and am wondering whether I've chosen the right way to do something, or if there are better/simpler ways to achieve what I want.
My specific example is that I'm constructing a User actor in response to a user logging into the system, and when constructing this actor there are two pieces of data I need in order to complete the construction of the actor.
If this were regular .NET code I might have something like the following...
public Task<User> LoadUserAsync (string username)
{
IProfileService profileService = ...;
IMessageService messageService = ...;
var loadProfileTask = profileService.GetUserProfileAsync(username);
var loadMessagesTask = messageService.GetMessagesAsync(username);
Task.WaitAll(loadProfileTask, loadMessagesTask);
// Now construct the user from the result of both tasks
var user = new User
{
Profile = loadProfileTask.Result,
Messages = loadMessagesTask.Result
}
return Task.FromResult(user);
}
Here I use WaitAll to wait for the subordinate tasks to complete, and let them run concurrently.
My question is - if I wanted to do the same in Akka.Net, would the following be the most regular way to do this? Pictorially I've created the following...
When I create my User actor, I then construct a (temporary) User Loader Actor, whose job it is to get the full user details by calling to the Profile actor and the Messages actor. The leaf actors that get the data are as follows...
public class UserProfileLoader : ReceiveActor
{
public UserProfileLoader()
{
Receive<LoadUserRequest>(msg =>
{
// Load the user profile from somewhere
var profile = new UserProfile();
// And respond to the Sender
Sender.Tell(profile);
Self.Tell(PoisonPill.Instance);
});
}
}
public class UserMessagesLoader : ReceiveActor
{
public UserMessagesLoader()
{
Receive<LoadUserRequest>(msg =>
{
// Load the messages from somewhere
var messages = new List<Message>();
// And respond to the Sender
Sender.Tell(messages);
Self.Tell(PoisonPill.Instance);
});
}
}
It doesn't really matter where they get the data from for this discussion, but both simply respond to a request by returning some data.
Then I have the actor that coordinates the two data gathering actors...
public class UserLoaderActor : ReceiveActor
{
public UserLoaderActor()
{
Receive<LoadUserRequest>(msg => LoadProfileAndMessages(msg));
Receive<UserProfile>(msg =>
{
_profile = msg;
FinishIfPossible();
});
Receive<List<Message>>(msg =>
{
_messages = msg;
FinishIfPossible();
});
}
private void LoadProfileAndMessages(LoadUserRequest msg)
{
_originalSender = Sender;
Context.ActorOf<UserProfileLoader>().Tell(msg);
Context.ActorOf<UserMessagesLoader>().Tell(msg);
}
private void FinishIfPossible()
{
if ((null != _messages) && (null != _profile))
{
_originalSender.Tell(new LoadUserResponse(_profile, _messages));
Self.Tell(PoisonPill.Instance);
}
}
private IActorRef _originalSender;
private UserProfile _profile;
private List<Message> _messages;
}
This just creates the two subordinate actors, sends them a message to get cracking, and then waits for both to respond before sending back all the data that's been gathered to the original requestor.
So, does this seem like a reasonable way to coordinate two disparate responses, in order to combine them? Is there an easier way to do this than craft it up myself?
Thanks in advance for your responses!
Thanks folks, so I've now simplified the actor significantly into the following, based on both Roger and Jeff's suggestions...
public class TaskBasedUserLoader : ReceiveActor
{
public TaskBasedUserLoader()
{
Receive<LoadUserRequest>(msg => LoadProfileAndMessages(msg));
}
private void LoadProfileAndMessages(LoadUserRequest msg)
{
var originalSender = Sender;
var loadPreferences = this.LoadProfile(msg.UserId);
var loadMessages = this.LoadMessages(msg.UserId);
Task.WhenAll(loadPreferences, loadMessages)
.ContinueWith(t => new UserLoadedResponse(loadPreferences.Result, loadMessages.Result),
TaskContinuationOptions.AttachedToParent & TaskContinuationOptions.ExecuteSynchronously)
.PipeTo(originalSender);
}
private Task<UserProfile> LoadProfile(string userId)
{
return Task.FromResult(new UserProfile { UserId = userId });
}
private Task<List<Message>> LoadMessages(string userId)
{
return Task.FromResult(new List<Message>());
}
}
The LoadProfile and LoadMessages methods will ultimately call a repository to get the data, but for now I have a succinct way to do what I wanted.
Thanks again!
IMHO that's a valid process, as you fork action and then join it.
BTW you could use this.Self.GracefulStop(new TimeSpan(1)); instead of sending poison pill.
You could use a combination of Ask, WhenAll and PipeTo:
var task1 = actor1.Ask<Result1>(request1);
var task2 = actor2.Ask<Result2>(request2);
Task.WhenAll(task1, task2)
.ContinueWith(_ => new Result3(task1.Result, task2.Result))
.PipeTo(Self);
...
Receive<Result3>(msg => { ... });
I've been Following this post To get my head around Lazy field of T, Which I think I understand, But I'm having trouble getting associated Field Data for a Part loaded this way
Aim - To show photo of blog post author on a blog post.
I want to add a content part "Content Author"
The part Editor should appear as a drop down list of orchard users.
(regardless of the content owner cms users should be able to pick the author)
I have added an image upload field to the User Content Type
I want to show the image of the user on the front end in the view for the Content Author Part
For the first part I have created the content type and used the lazy Filed of UserPart to get the username. However when I try and get the associated fields for the UserPart. There dosent seem to be any.
public class ContentAuthorRecord : ContentPartRecord
{
public virtual string AuthorEmail { get; set; }
}
public class ContentAuthorPart : ContentPart<ContentAuthorRecord>
{
internal readonly LazyField<UserPart> Owner = new LazyField<UserPart>();
public string AuthorEmail
{
get { return Record.AuthorEmail; }
set { Record.AuthorEmail = value; }
}
public UserPart Author
{
get { return Owner.Value; }
set { Owner.Value = value; }
}
public string AuthorName
{
get
{
if (Author == null)
return "Riders for health";
else
{
return Author.UserName;
}
}
}
}
public class ContentAuthorHandler :ContentHandler
{
private readonly IContentManager _contentManager;
public ContentAuthorHandler(IRepository<ContentAuthorRecord> repository, IContentManager contentManager)
{
_contentManager = contentManager;
OnActivated<ContentAuthorPart>(SetUpCustomPart);
Filters.Add(StorageFilter.For(repository));
}
private void SetUpCustomPart(ActivatedContentContext content, ContentAuthorPart part)
{
// Setup the getter of the lazy field
part.Owner.Loader(() => _contentManager.Query<UserPart, UserPartRecord>().List().FirstOrDefault(x => x.Email == part.AuthorEmail));
}
}
I would expect to be able to access the field with something like
(ImageUploadField.Fields.ImageUploadField)Author.Fields.FirstOrDefault(x
=> x.Name == "Photo");
form the within the part class
( although this makes every thing a bit brittle, hard coding a field name, but I'm not sure how eles to go about it)
Further Info
I have a HeaderPart with a Image field added via the cms (not in code) in the display handler I fetch the field like this
protected override DriverResult Display(HeaderPart part, string displayType, dynamic shapeHelper)
{
if (part.HeaderType == HeaderType.Full_width_hero_image)
{
var field = (ImageUploadField) part.Fields.FirstOrDefault(f => f.Name == "HeaderImage");
if (field != null)
{
return ContentShape("Parts_Header_ImageHero",
() => shapeHelper.Parts_Header_ImageHero(ImagePath: field.ImagePath, ImageTitle: field.FileName));
}
return null;
}
if (part.HeaderType == HeaderType.Full_width_hero_video)
{
return ContentShape("Parts_Header_VideoHero", () => shapeHelper.Parts_Header_VideoHero(VideoUrl: part.VideoUrl));
}
if (part.HeaderType == HeaderType.Body_width_video)
{
return ContentShape("Parts_Header_VideoBody", () => shapeHelper.Parts_Header_VideoBody(VideoUrl: part.VideoUrl));
}
return null;
}
This works, But I can do the same for a part loaded into a lazy field.
Cast to dynamic first, then the syntax becomes much simpler: ((dynamic)part.ContentItem).NameOfTheType.NameOfTheField.NameOfTheProperty
If you have added the fields to the User content type via the CMS interface, it may have added the fields to a different part to the one you expect. If you are adding fields to the User content type, by default it will have added the fields to a new part called 'User', not 'UserPart'. Try to following to search all parts in the content item:
(ImageUploadField.Fields.ImageUploadField)Author.ContentItem.Parts
.SelectMany(p => p.Fields).FirstOrDefault(f => f.Name == "Photo");
or directly from the 'User' part:
(ImageUploadField.Fields.ImageUploadField)Author.ContentItem.Parts
.First(p => p.PartDefinition.Name == p.ContentItem.ContentType).Fields
.FirstOrDefault(f => f.Name == "Photo");