I am using laravel 5.2 to develop an application. Now what I need is I have two tables first one is users and second one is groups. Groups table is the parent table of the users table where groups_id is the column with foreign key with groups table (group_id). Now when login I am using the code as follows:
$users = User::leftJoin('groups', 'groups.group_id', '=', 'users.groups_id')->where('email', base64_decode(base64_decode(trim($request->input('user_login')))))->first();
where i used join to join the groups table. But It is executing perfectly but does not show the data in the session (Auth::user()).
So please suggest me how to add the second table in the session but only join the row with foreign key records.
Thanks.
You have define a relation in User Model like this
class User extends Authenticatable
{
......
/*
* Relation to Group Model
*
*/
public function group()
{
return $this->belongsTo('App\Models\Group','group_id','group_id');
}
......
}
Now you can access authored user group at anytime , anywhere by these line of code
auth()->user()->group()
or
$user = User::find($id);
$user->group();
and to retrieve users from a group you can define reverse of this relation in Group Model like this
class Group extends Mdoels
{
..........
public function Users()
{
return $this->hasMany('App\Models\Users','group_id','group_id');
}
..........
}
you can find more information on docs here
Related
I'm Trying to get the number of user in a specific group, I've done the following :
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<Long> q = cb.createQuery(Long.class);
q.select(cb.count(q.from(User.class))).where(cb.equal(q.from(User.class).get("userGroup"), groupId));
But instead of getting the number of user in a group , I get this number multiplied by the number of all users in my table, the generated ORM request looks like this :
Hibernate: select count(*) as col_0_0_ from app_user user0_ cross join app_user user1_ where user1_.user_group=1
EDIT :
This is my user Model :
public class User {
private String userFirstName;
private String userLastName;
/* some stuff */
#ManyToOne
private Group userGroup;
}
And my group model has an int attribute annotated with #Id and named id. How Can I get the number of user by group id in this case ?
This is the expected behaviour. CriteriaQuery is mutable and every time you call from(), it
Create and add a query root corresponding to the given entity, forming a cartesian product with any existing roots. (Javadoc of Java EE)
To achieve predictable result please create Root once and use the reference.
CriteriaQuery<Long> q = cb.createQuery(Long.class);
Root<User> u = q.from(User.class);
q.select(cb.count(u)).where(cb.equal(u.get("userGroup"), groupId));
Within above code u plays same role as in this query
SELECT u.name FROM User u
Explaining it further, calling from() twice would be equivalent of
SELECT u1, u2 FROM User u1, User u2
I'm using code first to create my DB but have to match a given schema.
I have an Org entity (simplified here) an Org can have many children of type org
public class Org
{
public int Id {get;set;}
public virtual IList<Org> Children{get;set;}
}
I want to generate an Org table and a table called OrgRelationship which has two columns ParentId and ChildId. The data is being provided to us in that format but I'd really like EF to expand the table into this model...
Is it possible to generate this join table just with an EntityTypeConfiguration on model builder? Do I have to have an OrgRelationship class?
This doesn't seem to cut it
public class OrgMap : EntityTypeConfiguration<Org>
{
public OrgMap()
{
HasKey(n => n.Id);
HasMany(n => n.Children);
}
}
You can configure the join table using the following calls.
HasMany(n => n.Children).WithMany().Map(
m => m.ToTable("OrgRelationship").MapLeftKey("ParentId").MapRightKey("ChildId"));
i am facing problem to fetch out records from table using Yii relationship,
i have 3 tables
1) Students -> ID, Name, Roll_Number
2) Subjects -> ID, Name
3) Students_taken_Subjects -> ID, Student_ID, Subject_ID
Suppose there are number of students have taken more than one subjects which are stored in the 3rd table "Students_taken_Subjects" then how i can fetch out the list of students taken any specific subject?
e.g. list of students taken maths
which one from below relationships are correct and how can i get results into the $dataProvider variable?
'Students'=>array(self::HAS_MANY, 'Subjects', 'Student_ID'),
and
return array(
'Students'=>array(self::MANY_MANY, 'Subjects',
'Students_taken_Subjects(student_id, subject_id)'),
);
The relationship between Subjects and Students is MANY_MANY, but you've written it a bit wrong, This is what you need:
class Subjects extends CActiveRecord
{
// ...
public function relations()
{
return array(
'Students'=>array(self::MANY_MANY, 'Students', 'Students_taken_Subjects(Subject_ID, Student_ID)'),
);
}
// ...
}
Once you've written this relation, the Subjects active record will have a Students property that returns an array with the 0 or more students taking that subject. You can access them like this:
$subject = Subjects::model()->findByPk($pk);
$students = $subject->Students; // an array with the subject's students
The above code will result in two DB accesses, one for the $subject and one for the related $students. This might be fine, but if you are accessing a lot of subjects it could become a problem with too much "lazy loading". You can tell Yii to "eager load" the students along with the subjects like this:
$subjects = Subjects::model()->with('Students')->findAll();
Here you are finding all of the subjects, but alerting Yii--using with('Students')--that you'll be wanting each subject's student information as well. This ensures that all of the students related to the subjects you find will be grabbed at once. An alternative to the with() function is to use a criteria's with property:
$criteria=new CDbCriteria;
$criteria->with = array('Students');
$subjects = Subjects::model()->findAll($criteria);
Either way, when you do ask for a subject's students like this:
$subjects[0]->Students;
$subjects[1]->Students;
// ...
you will not get another DB call each time because Yii already loaded the data.
You'll need to provide more details about what you are wanting to do with the students in the data provider before I can give any more details about that.
Here's my table structure
Places
PlaceId PK
Name
...
PlaceCategories
CatId PK
Name
...
PlaceCats
PlaceId PK
CatId PK
Here's my query that pulls Places based on category id (table join)
public static IQueryable<Places> ByPlaceCat(this Table<Places> table, Expression<Func<PlaceCats, bool>> predicate) {
var db = (DataContext)table.Context;
var innerBizBase = db.PlaceCats.Where(predicate);
return db.Places.Join(innerBizBase, a => a.PlaceId, ab => ab.PlaceId, (a, ab) => a);
}
I use it like this:
places = Db.Places.ByPlaceCat(a => a.CatId == 5);
But I want to be able to pull based on a List<int> of category id's. Looking through the generated PLINQO code, a query that pulls by multiple PlaceId's (but not using a joined table) looks like this:
public static IQueryable<Places> ByPlaceId(this IQueryable<Places> queryable, IEnumerable<long> values)
{
return queryable.Where(p => values.Contains(p.PlaceId));
}
How could I essentially merge those two queries, to let me pass in a List<int> of CatId's to query by? This LINQ/PLINQO query is melting my brain. Thanks in advance!
You would need to write a extension method like this:
public static IQueryable<Places> ByPlaceCats(this Table<Places> table, IEnumerable<int> catIds)
{
var db = (TestDataContext)table.Context;
var places = (from placeCat in db.PlaceCats
join place in db.Places on placeCat.PlaceId equals place.PlaceId
where catIds.Contains(placeCat.CatId)
select place);
return places;
}
Please note that the PlaceCats table could be made into a ManyToMany relationship by adding two foreign keys to the proper tables. Once this change has been made than PLINQO will automatically generate the correct code and will create a link between the two tables skipping the intermediary table. So you could get a collection of PlaceCategories associated to the current Places entity by accessing a property on the Places entity.
Please remember to contact us if you have any questions and be sure to check out the community forums located here and PLINQO forums here.
Thanks
-Blake Niemyjski (CodeSmith Support)
I have the following issue in the project I am working on. Each transaction in the system is assigned to a given user. So there is a many to one relationship between transactions and users, like so:
public class User
{
public int ID { get; private set; }
public string FirstName { get; set; }
....
}
public class Transaction
{
public int ID { get; private set; }
public User CreatedBy { get; private set; }
...
}
I have mapped these entities with NHibernate so that there is a many-to-one mapping between the Transaction and the User classes. The User object doesn't have a list of transactions, but the Transaction has a reference to the User that created it.
Now I want to query to retrieve a list of the users who created the most transactions, but I can't figure out how to get the top 10 most referenced users using NHibernate.
Any ideas? I would like to be able to use ICriteria to complete this rather than HQL, but HQL would be ok if required.
Update
I tried sirrocco's suggestion with the query as...
DetachedCriteria topReferencedUsers = DetatchedCriteria.For(typeof(Transaction))
.SetProjection(Projections.GroupProperty("CreatedBy.Id"))
.SetProjection(Projections.Count("CreatedBy.Id").As("pcount" ))
.AddOrder(Order.Desc("pcount"))
.SetMaxResults(10);
and build that as the subquery...
GetSession().CreateCriteria(typeof (User))
.Add(Subqueries.PropertyIn("Id", topReferencedUsers))
.List<User>();
but this subquery does not group but returns the total number of transactions, which are then used as the IN clause to the User query. If I add the ProjectionList() with both projections, I get the output of the subquery that I want, but it fails because it tries to run the two column output into the IN clause of the User query. How do I get NHibernate to project both the ID and the Count, but only join on the ID?
Update (2)
I tried Sirrocco's SqlGroupProjection suggestion (thank you Sirrocco) but came up empty. First it gave me errors saying that it couldn't find the property pcount, which meant that I needed to remove the order by, which means it was ordering by some timestamp, which won't work. But even with that, it is still only outputing the count of the times that the user was referenced, not the user id with which to join the Users table. Any ideas? Thanks.
You can try it for yourself and see if you get the desired output.
var userIds = this.Session
.CreateQuery(#"
select a.User.Id
from Transaction as a
group by a.User
order by count(a.User) desc")
.SetMaxResults(10)
.List<int>().ToArray();
var users = this.Session.CreateCriteria(typeof(User))
.Add(Restrictions.InG("Id", userIds))
.List<Artist>();
return users;
The userId's that I get from the first queries are (90,22,50,55) but when passed to the second one I get my users in 22,50,55,90 order.
You could split the operation into two steps.
1) Execute topReferencedUsers, then extract the CreatedBy.Id projection into an int array in memory (since you're only dealing with 10).
2) Then Execute:
GetSession().CreateCriteria(typeof(User))
.Add(Expression.InG<int>("Id", topTenIdArray))
.List<User>();