Laravel Eloquent activity feed - eloquent

I'm trying to create a simple activity feed where a user can see his friends' updates.
I'm dealing with three tables. user_status, friendship and users.
users table
user_id
name
email
..(a regular users table, nothing special)
friendship table
friendship_id
friend_one (Foreign key from users table)
friend_two (Foreign key from users table)
user_status table
status_id
user_id (foreign key from users table)
status
date
MODELS
User Model
public function friends() {
return $this->belongsToMany('App\Models\User', 'friendship', 'friend_one', 'friend_two');
}
public function status() {
return $this->hasMany('\App\Models\UserStatus','status_id');
}
UserStatus Model
public function usersStatus() {
return $this->belongsTo('\App\Models\User','user_id');
}
FeedController.php
class FeedController extends Controller
{
public function index() {
$friends = Auth::user()->friends;
return view('frontend.feed.index')
->with('friends',$friends);
}
}
Using the query below, I can get a user's friends. I also can get a specific user's status updates easily, but I have no idea how to list only specific users' statuses.
#foreach($friends as $friend)
{{$friend->email}}
#endforeach
The one below doesn't work.
View
#foreach($friends as $friend)
#foreach($friend->status as $status)
{{$status->status}}
#endforeach
#endforeach
Invalid argument supplied for foreach() (View: /Applications/MAMP/htdocs/master/resources/views/frontend/feed/index.blade.php)

I think the problem is with your foreign_key reference in
public function status() {
return $this->hasMany('\App\Models\UserStatus','status_id');
}
Change to :
public function status() {
return $this->hasMany('\App\Models\UserStatus', 'user_id', 'user_id');
}
and it should work.

Related

Eloquent Relationship Laravel 5.4

I have three tables as follows users, jobs and job_statuses with the following simple schema.
**Users Table**
id, user_id, email, password
**Jobs Table**
id, user_id, title, description, status_id
**Job_statuses Table**
id, status
I have successfully retrieved a list of Jobs posted by an authorized user using a one-to-many relationship but I can't get hold on the status using the status_id
User Model
public function job(){
return $this->hasMany(Job::class, 'user_id')->take(5);
}
Job Model
public function user() {
return $this->belongsTo(User::class, 'user_id');
}
public function jabstatus() {
return $this->hasOne(JabStatus::class, 'status_id', 'id');
}
Job_Statuses Model
public function statuses() {
return $this->belongsTo(Job::class, 'id', 'status_id');
}
When try doing something like:
#foreach($user->job as $job)
{{$job->statuses->status}}
#endforeach
I get an error from this: {{$job->statuses->status}}
A well explained answer will do, thanks.
Finally was able to get what I wanted.
What I had was a multiple eloquent relationship.
Job Model
public function jobstatus() {
return $this->hasOne(JobStatus::class, 'id');
}
JobStatus Model
public function status() {
return $this->belongsTo(Job::class);
}
Then:
$user = User::with(['profile', 'review', 'job.jobstatus'])->find(Auth::User()->user_id);
return view('user.dashboard', ['user' => $user]);
Then on my View:
#foreach(#$user->job as $job)
{{$jab->jobstatus->status}}
#endforeach

How to get country name for users in laravel 5.1

Hello i have two tables users and countries, and each user belongs to the country. So i created two models User and Country
In User Model i put
public function country_living()
{
return $this->belongsTo('App\Country');
}
In country Model i put
public function users()
{
return $this->hasMany('App\User');
}
Now when i am selecting all users for listing in backed i am using below code
$users = User::where('user_type', 'customer')->get();
and in view i am using #foreach($users as $user)
to display all the user information, i don't know that country name is coming by query or not and if it is coming how to show it. when i use dd() on $user there is no information about country.
UserModel
public function Country()
{
return $this->belongsTo('Country');
}
Countrymodel
public function User()
{
return $this->hasMany('User');
}
View.php
#foreach($User as $user)
{{$user->id}}
{{$user->name}}
{{$user->country_id}}

Add related database entry in Azure Mobile Services controller

In my Azure Mobile Service I have a controller class UserController : TableController<User> and in it is a get method:
// GET tables/User/48D68C86-6EA6-4C25-AA33-223FC9A27959
public SingleResult<User> GetUser(string id)
{
return Lookup(id);
}
I want to record each time a user is accessed and so I add a simple type to the model:
public class UserVisit : Microsoft.WindowsAzure.Mobile.Service.EntityData
{
public string VisitingUser { get; set; }
public DateTime TimeOfVisit { get; set; }
}
and include the property public DbSet<UserVisit> UserVisits { get; set; } in my VCollectAPIContext : DbContext class (and update the database with a code-first migration).
To add a UserVisit to the database when a user id is queried I change my controller method to
// GET tables/User/48D68C86-6EA6-4C25-AA33-223FC9A27959
public async Task<SingleResult<User>> GetUser(string id)
{
var userVisit = new UserVisit { VisitingUser = id, TimeOfVisit = DateTime.UtcNow };
context.UserVisits.Add(userVisit);
await context.SaveChangesAsync();
return Lookup(id);
}
But the SaveChangesAsync fails with a System.Data.Entity.Validation.DbEntityValidationException. Digging around in the exception's EntityValidationErrors property I find that the problem is "The Id field is required."
That's a little odd. The Id field is one of the properties in the base-class Microsoft.WindowsAzure.Mobile.Service.EntityData that I would expect to be added automatically on insert. No matter, I can add it and several of the other base-class's properties thus:
// GET tables/User/48D68C86-6EA6-4C25-AA33-223FC9A27959
public async Task<SingleResult<User>> GetUser(string id)
{
var userVisit = new UserVisit { Id = Guid.NewGuid().ToString(), Deleted = false, VisitingUser = id, TimeOfVisit = DateTime.UtcNow, CreatedAt = DateTimeOffset.Now };
context.UserVisits.Add(userVisit);
await context.SaveChangesAsync();
return Lookup(id);
}
This time I get a System.Data.Entity.Infrastructure.DbUpdateException because we "Cannot insert the value NULL into column 'CreatedAt'". It was not null in the call to Add. So CreatedAt has been set to null somewhere outside my code and then the insert fails as a result!
I also tried setting up an EntityDomainManager<UserVisit> userVisitDomainManager; instance variable in the controller's initializer, and then rewriting my controller get method as
// GET tables/User/48D68C86-6EA6-4C25-AA33-223FC9A27959
public async Task<SingleResult<User>> GetUser(string id)
{
var userVisit = new UserVisit { VisitingUser = id, TimeOfVisit = DateTime.UtcNow };
await userVisitDomainManager.InsertAsync(userVisit);
return Lookup(id);
}
That fails with the same message, "Cannot insert the value NULL into column 'CreatedAt'"
How should I perform the seemingly simple task of inserting a related data item within my controller method?
The solution is likely similar to this answer. I'm guessing that your migration is not using the Mobile Services SqlGenerator so some of the custom SQL settings aren't getting applied. What that means is that:
Id doesn't get a default value of NEWID() -- this explains your "Id field is required" error.
CreatedAt doesn't get a default value of SYSUTCDATETIME() -- this, combined with the [DatabaseGenerated] attribute on EntityData.CreatedAt, explains the "NULL CreatedAt" error.
Try updating your migration according to the link above and see if that works for you.
To fix the problem of "The Id field is required" following brettsam's instructions.
Add this in your model:
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
[TableColumn(TableColumnType.Id)]
public new string Id { get; set; }
It will auto generate a GUID when you add an entity.

Filtering table from another table in vaadin

I was wondering how to filter one table based on what I click on in another table. For example if I click on Russia in the country table it should filter all the people from Russia in the name table. I would like to know how to do this using vaadin. I added some relevant code below. The country table is suppose to filter the name table when I click on a country.
Here is my filter method:
public class CountryFilter implements Filter {
public String needle;
public CountryFilter(String needle) {
this.needle = needle;
}
public boolean appliesToProperty(Object id) {
return true;
}
public boolean passesFilter(Object itemId, Item item) {
String haystack = ("" + item.getItemProperty(Name) +
item.getItemProperty(Country)).toLowerCase();
return haystack.contains(needle);
}
}
Here is my search method that uses the filter
public void initCountrySearch() {
country.setSelectable(true);
country.setImmediate(true);
name.setVisibleColumns(new String[] {"name"});
country.setVisibleColumns(new String[] {"country"});
country.addValueChangeListener(new Property.ValueChangeListener() {
public void valueChange(ValueChangeEvent event) {
// TODO Auto-generated method stub
data.name.removeAllContainerFilters();
data.name.addContainerFilter(new CountryFilter(event.getProperty().getValue().toString()));
}
});
}
You could set a ValueChangeListener on your selection criteria table which informs you about, well, a value change. In the value change method you can get the selected item and according to this item you do a loading on your target table.

SaveChanges doesn't work for TPH entities

I use Entity framework with Generate T-SQL Via T4 (TPH).xaml (VS) and SSDLToSQL10.tt (VS) templates.
I have a table
TABLE [dbo].[Users](
[UserId] [int] IDENTITY(1,1) NOT NULL,
[UserName] [nvarchar](100) NOT NULL,
[Password] [nvarchar](50) NOT NULL,
[IsPaid] [bit] NOT NULL
Since I have 2 user types, field IsPaid is the discriminator. I created TPH in my model. Classes generated via .tt are
public abstract partial class User
{
public User()
{
}
public int UserId { get; set; }
public string UserName { get; set; }
public string Password { get; set; }
public partial class RegularUser : User
{
}
public partial class PaidUser : User
{
}
public Container()
: base("name=Container")
{
this.Configuration.LazyLoadingEnabled = false;
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
throw new UnintentionalCodeFirstException();
}
public DbSet<User> Users { get; set; }
Let's say I have Regular user with id 3. I create a new paid user u with the same data and try to save it.
using (var entities = new Container())
{
entities.Entry(u).State = u.UserId == 0 ? EntityState.Added : EntityState.Modified;
entities.SaveChanges();
}
Nothing happens. And I can see from the profiler that the query doesn't use IsPaid column at all. Can anyone help?
Are you trying to change regular user with Id = 3 to paid user with Id = 3? That is not possible without executing direct SQL update. From perspective of EF the entity type is permanent. It is same like when you work with objects - you cannot "convert" regular user to paid user without creating whole new instance which will have different memory allocation (= different Id).
If your business logic expects that regular user can become paid user than EF inheritance is not a solution because it cannot do that. The only way to "change" regular user to paid user is creating whole new instance of paid user, inserting it to database and deleting old instance of regular user (sure you must also fix all relations from user to other entities).