How to select by fields in preloaded object? - go

I wonder if it is possible to select by a condition in a preloaded object. For example, I have tables User and Profile (one to one). So I need to get all Users with Profiles where sex is female.
I thought it can be done by something like this:
Preload("UserProfile").Where("user_profile.sex = ?", "female")
But it returns something like:
pq: missing FROM-clause entry for table \"user_profile\"

Preloading doesn't join the tables specified. You need to explicitly join the table in question:
Preload("UserProfile").Joins("LEFT JOIN user_profile ON user.id = user_profile.user_id")
.Where("user_profile.sex = ?", "female")
...Assuming your primary key is called id, and foreign key is called user_id.

I also faced the same issue in a recent project. I found the below solution to work for me.
var users []User
Preload("UserProfile","sex = ?","female").Find(&users)
and then check for
user.profile!=nil
The issue in this approach is it will load all users.
But in your case, it can be another way around.
var profiles []Profile
Preload("User").where("sex = ?","female").Find(&profiles)
I hope this will solve your problem.

Related

Laravel inject SQL Query into Model Collection

I have a Laravel Controller method with the following code:
$listings = LikedListing::where('user_id', '=', $user->id)
->with('Listing.Photos')
->get();
This should return a collection of LikedListing records with Photos attached to each likedlisting record.
I have this SQL Query I need to inject into each record as well:
select u.id, l.address, u.first_name, u.last_name, ll.score
from listings l
left join liked_listings ll on ll.listing_id = l.id
left join users u on u.id = ll.user_id
where u.id in (
select secondary_user
from user_relationships
where primary_user = $primaryUser
)
and ll.listing_id = $listingId
Where $primaryUser = $user->id And $listingId is equal to the listingid inside each record in the collection.
I have absolutely no idea how to do this.
Maybe theres a model way of performing this? UserRelationship model has a primary_user column, which connects to a $user->id, and there is a secondary_user column, which acts like a follower userid, which is what we need in the final result (a list of all related users per listing)`
Can someone who has much far superior knowledge with Laravel please assist
My goal is to have the current collection of listing records with associated photos as well as following users (secondary_user) from the user_relationship table related to the primary_user (the logged in user) who have a record using user_id with the secondary_user value for that listing in the likedlisting table (obv assoicated with the listing_id). I already provided a raw sql query if thats the only option.
So in simple terms all related users who have liked a listing that the primary user has liked as well should be added to each listing record

Rails selecting aliases in query

So I have 2 tables actor and actor2role. The latter is a lookup (junction) table to relate actor, role and dvd. I need to create a query with aliases, so I have this method:
def self.remove_duplicate_by_id(id)
offendingActor = self.find(id).actor # get the actor's name
ids = self.find_by_sql("SELECT MIN(id) AS minId, MAX(id) AS maxId, actor FROM `dvd_actor` WHERE actor = '#{offendingActor}'")
rolesForOffender = ids.actor2role # throws error
end
The problem is that ids is not an ActiveRecord object so I can't use the actor2role method (which is a relationship I've established between the 2 tables in Rails and works when you do something like Actor.first.actor2role.
so the questions is: Am I doomed to do this manually and then issue another sql query to recreate what the actor2role method would accomplish or is there some way to do this with Rails objects?
I'd really like to do it all natively if possible because I also have to issue these queries:
UPDATE dvd_actor2role SET actorid = $d->minId WHERE actorId = $d->maxId");
DELETE FROM dvd_actor2role WHERE actorId = $d->maxId LIMIT 1");
Is this even possible?
In the end I went with this which seems to do the trick. If anyone can spot any code that could be optimized, or something inherently wrong (and feels like chiming in) please feel free to comment.
actorObject = self.find_by_id(id) # get the object because we need it below for other queries
offendingActor = actorObject.actor
ids = self.select("MIN(id) AS minId, MAX(id) AS maxId, id, actor").find_by_actor(offendingActor)
rolesForOffender = actorObject.actor2role
rolesForOffender.each do |r|
# first find out if the relationship already exists or we get a SQL error for the foreign key relationship.
exists = Actor2role.where("actorId = ? AND roleId = ?", ids.minId, r.roleId)
if exists.nil?
Actor2role.update_all("actorId = #{ids.minId}, actorId = #{ids.maxId}")
end
end
self.destroy(ids.maxId) # delete this guy in actor table
end

With the use of Apex code, how can I select all ''OpportunityProducts' objects which are belongs to particular 'Opportunity Id'

I am way to customizing 'Sales' application that belongs to 'salesforce.com' platform.
Is there any way to select all the 'OpportunityProducts' objects which are belongs to particular 'Opportunity Id' ?
[SELECT Id FROM OpportunityProduct WHERE Opportunity =:opportunitId];
When I execute above code for select those 'OpportunityProduct', I got following error. If any one have some idea please update me. Thanks.
Save error: sObject type 'OpportunityProduct' is not supported. If you are attempting to use a custom object, be sure to append the '__c' after the entity name. Please reference your WSDL or the describe call for the appropriate names.
Another way to get this done when you need the actual products, not just the line items, is as follows. First get your opportunities:
List<Opportunity> opps = [SELECT Id, Name FROM Opportunity LIMIT 1000];
Then loop through to create a list of opportunity Ids
List<Id> oppIds = new List<Id>();
for(Opportunity o : opps)
{
oppIds.add(o.Id);
}
Now get your actual products that belong to your opportunities...
List<OpportunityLineItem> oppProds = [SELECT Id, PricebookEntry.Product2.Name, PricebookEntry.Product2.Family
FROM OpportunityLineItem
WHERE OpportunityId IN :oppIds];
Hope that helps.

LINQ Noob, how do I write this common query?

I'm a long time dev, but still kind of new to LINQ. I'm OK when dealing with one set of object, but things get tougher when I need to pull from several sources, and I could use some guidance in getting what I need here.
I have three tables in my database, two related tables and one that holds the PK/FK to tie them together. So something like:
Users
UserID
UserName
Surveys
SurveyID
SurveyName
UserSurveys
UserID
SurveyID
I am using EF and so all of this data has been pulled into Objects.
So... what I want to do is return a List of all Surveys that are associated with a given User. So something like (pseudo-code):
// currentUserID = the UserID I need to get matching Surveys for
var surveys = from Survey where (s => s.SurveyID == UserSurvey.SurveyID && UserSurvey.UserID == currentUserID);
I assume I need to make a sub-query and use a Contains() or something like that, but I keep tripping over myself. Help?
Should be something like this:
from us in UserSurveys
where us.UserId == currentUserID
join s in Surveys on us.SurveyID equals s.SurveyID
select s
If this is EF you should be able to do someUser.Surveys.
Assuming your database and entity model has all of your FK references you should be able to do something like this....
// currentUserID = the UserID I need to get matching Surveys for
var surveys = from s in Survey
where s.User.UserID == currentUserID
select s;

Table with a foreign key

how can I build a table of "orders" containing "IdOrder", "Description" and "User"?... the "User" field is a reference to the table "Users", which has "IdUser" and "Name". I'm using repositories.
I have this repository:
Repository<Orders> ordersRepo = new OrderRepo<Orders>(unitOfWork.Session);
to return all Orders to View, I just do:
return View(ordersRepo.All());
But this will result in something like:
IdOrder:1 -- Description: SomeTest -- User: UserProxy123ih12i3123ih12i3uh123
-
When the expected result was:
IdOrder:1 -- Description: SomeTest -- User: Thiago.
PS: I don't know why it returns this "UserProxy123ih12i3123ih12i3uh123". In Db there is a valid value.
The View:
It is showed in a foreach (var item in Model).
#item.Description
#item.User //--> If it is #item.User.Name doesn't work.
What I have to do to put the Name on this list? May I have to do a query using LINQ - NHibernate?
Tks.
What type of ORM are you using? You mention "repositories" but does that mean LinqToSql, Entity Framework, NHibernate, or other?
It looks like you are getting an error because the User field is not loaded as part of the original query. This is likely done to reduce the size of the result set by excluding the related fields from the original query for Orders.
There are a couple of options to work around this:
Set up the repository (or context, depending on the ORM) to include the User property in the result set.
Explicitly load the User property before you access it. Note that this would be an additional round-trip to the database and should not be done in a loop.
In cases where you know that you need the User information it would make sense to ensure that this data in returned from the original query. If you are using LinqToSql take a look at the DataLoadOptions type. You can use this type to specify which relationships you want to retrieve with the query:
var options = new DataLoadOptions();
options.LoadWith<Orders>(o => o.User);
DataContext context = ...;
context.LoadOptions = options;
var query = from o in context.Orders
select o;
There should be similar methods to achive the same thing whatever ORM you are using.
In NHibernate you can do the following:
using (ISession session = SessionFactory.OpenSession())
{
var orders = session.Get<Order>(someId);
NHibernateUtil.Initialize(orders.User);
}
This will result in only two database trips (regardless of the number of orders returned). More information on this can be found here.
In asp.net MVC the foreign key doesn't work the way you are using it. I believe you have to set the user to a variable like this:
User user = #item.User;
Or you have to load the reference sometimes. I don't know why this is but in my experience if I put this line before doing something with a foreign key it works
#item.UserReference.load();
Maybe when you access item.User.Name the session is already closed so NHib cannot load appropriate user from the DB.
You can create some model and initialize it with proper values at the controller. Also you can disable lazy loading for Orders.User in your mapping.
But maybe it is an other problem. What do you have when accessing "#item.User.Name" from your View?

Resources