I have two models Member and Saving with
Member('id','name')
Saving('id','member_id','amount','month')
I have to restrict duplicate entry of saving of a member for a given month.
Member.php
class Member extends Model
{
protected $fillable=['name','address','phone'];
public function loan()
{
return $this->hasOne(Loan::class,'member_id','id');
}
public function savings()
{
return $this->hasMany(Saving::class,'member_id','id');
}
}
Saving.php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Saving extends Model
{
protected $fillable=['amount','month','member_id'];
public function member()
{
return $this->belongsTo('App\Member','member_id','id');
}
}
Is it possible to implement restriction, using functions in model, or controller?
EDIT:
this is how i tried.
SavingController.php
public function addSaving(Request $request){
if($request->isMethod('get')){
$memberData = Member::all();
return view($this->_pagePath.'saving.addsaving',compact('memberData'));
//return redirect()->back();
}
if($request->isMethod('post')){
$this->validate($request,[
'amount' => 'required',
'month' => 'required'
]);
$data['amount'] = $request->amount;
$data['month'] = $request->month;
$data['member_id']= $request->name;
$member= Member::find(1);
if($member->savings()->where('month',$request->month)->exists())
{
return 'Savings for this month are already added.';
}
else
{
if(DB::table('savings')->insert($data)){
return redirect()->route('saving')->with('success','data was successfuly inserted');
}
}
}
}
An enum is a wrong column for month my friend, unless you don't care for the year. Because this way you will just be able to store savings for each month, but not for each year separately.
Your relationship is set correctly, so you can then make a check like this:
// considering you have the specific member selected
$member = Member::find('ID_OF_THE_MEMBER');
if($member->savings()->where('month', APRIL)->exists())
{
return 'Savings for this month are already added.';
}
Related
I have one main table and two detail tables
table names: tb_main, tb_detail1, tb_detail2
tb_main
id, detail_code
tb_detail1
id, main_id
tb_detail2
id, main_id
I want get detail data using one function in main model
public function detail()
{
if(detail_code == 1)
return $this->hasOne(Detail1::class, 'main_id', 'id');
else
return $this->hasOne(Detail2::class, 'main_id', 'id');
}
Any ideas? please help me!
And sorry for my bad English.
You can use $this->detail_code
public function detail() {
if($this->detail_code == 1) {
return $this->hasOne(Detail1::class, 'main_id', 'id');
}else{
return $this->hasOne(Detail2::class, 'main_id', 'id');
}
Don't do that in the relation method. First, declare all relations in the main model like so:
public function detail1()
{
return $this->hasOne(Detail1::class, 'main_id');
}
public function detail2()
{
return $this->hasOne(Detail2::class, 'main_id');
}
Then write one method to decide what to do based on detail_code :
public function detail()
{
if($this->detail_code == 1)
return $this->detail1()->first();
return $this->detail2()->first();
}
Rating model
class Rating extends Model
{
protected $fillable = [
'owner_id', 'toilet_id','user_id','rating','desc',
];
public function toilet()
{
return $this->belongsTo(ToiletInfo::class);
}
}
ToiletInfo model
class ToiletInfo extends Model
{
protected $fillable = [
'owner_id', 'toilet_name','price','complex_name','address','toilet_lat','toilet_lng','status',
];
public function owner()
{
return $this->belongsTo(ToiletOwner::class);
}
public function ratings()
{
return $this->hasMany(Rating::class,'toilet_id');
}
}
RatingController
public function index()
{
return $toilets = ToiletInfo::with('ratings')->get();
//return view('admin.rating',compact('toilets'));
}
I want to get the average of rating but how to access elements inside ratings[]
Or help me improve the method I am using to get ratings for toilets that are reviewed by users
From what I understand from your question you want to get the average rating.
In your ToiletInfo model, add a new method:
public function getAverageRating()
{
$ratings = $this->ratings;
$count = $ratings->count(); // total count
$total_ratings = $ratings->sum('rating'); // add the 'rating' for all rows
return $total_ratings / $count; // average
}
In your blade file, you can simply do
$toilet->getAverageRating()
Which will give the average rating.
I have a controller that should return a list of categories. Each should also have a collection of sub-categories. Each sub-category should also have modules. The modules are of two types: the latest modules and most watched modules.
A SUMMARY STRUCTURE I WANT:
[
{
id: 1,
name: category 1,
sub_categories:
[
{
id: 1,
name: subcategory 1:
modules:
[
latestModules: [...],
mostViewedModules[...]
]
}
],
another sub-category object,
and another sub-category object
},
another category object,
and another category object,
]
My Controller
class SeriesController extends Controller
{
public function getSeries()
{
$categories = Category::with('SubCategories')->get();
$countCats = 0;
$countSubCats = 0;
collect($categories)->map(function ($category) use ($countCats, $countSubCats, $categories){
collect($category->subCategories)->map(function ($subCategory) use ($countSubCats, $categories) {
collect($categories[$countCats]->subCategories[$countSubCats])
->put('modules',
SubCategory::with('latestModules', 'mostViewedModules')
->where('id', $subCategory->id)->get()
);
$countSubCats++;
});
$countCats++;
});
return $categories;
}
}
My Category model
class Category extends Model
{
public function subCategories()
{
return $this->hasMany('App\SubCategory')
->orderby('name');
}
}
My Subcategory Model
class SubCategory extends Model
{
public function parentCategory(){
return $this->belongsTo('App\Category', 'category_id');
}
public function modules()
{
return $this->belongsToMany('App\Module', 'module_category', 'sub_category_id', 'module_id');
}
public function latestModules()
{
return $this->modules()
->orderBy('created_at', 'desc');
}
public function mostViewedModules()
{
return $this->modules()
->orderBy('views', 'desc');
}
}
My Module Model
class Module extends Model
{
public function subCategories()
{
return $this->belongsToMany('App\SubCategory', 'module_category', 'module_id', 'sub_category_id');
}
}
WHAT I WAS TRYING TO DO
1) Get all the categories via Eloquent Query
2) Collect the many categories and Map over them
3) For each ONE category i map over again to single it out into sub-categories
4) For each sub-category i run Eloquent query to return the related modules.
5) Then i put that result into categories original array by using PUT. I wanted to expand on the original $categories array by including the modules.
PROBLEM
I realize that the loop works and everything is fine, except that the global $categories variable does not update. Its like inside the loops its updated but once we exist the Map loops the value defaults to
Category::with('SubCategories')->get()
public function beforSave($option = array()) {
if($this->columnName) {
// Statement
}
}
Something like that
if(!$this->loadModel($type)) {
// Statement
}
Get the model schema
$this->modelName->schema();
Check if my field is available or not
if (!empty($this->modelName->schema('date_created'))) {
// statement
}
Or
public function beforeSave($options = array()) {
if ($this->hasField('date_created')) {
$this->data[$this->alias]['date_created'] = date('Y-m-d H:i:s');
}
}
Try with getColumnType and array_key_exist;
getColumnTypes() Returns an associative array of field names and column
types.
$fileds = $this->YourModelName->getColumnTypes();
if(array_key_exists('columnName', $fileds)) {
// Statement
}
I want that when a record is saved and marked as active, all other records are marked INactive.
I've tried the following code in my model:
public function beforeSave($options = array()) {
if (!empty($this->data['Ticket']['is_active'])) {
$this->data['Ticket']['is_active'] = 0;
}
return true;
}
However this code is error
Use afterSave
Instead of using beforeSave, it's more appropriate to use afterSave, and updateAll like so:
public function afterSave($created) {
if (!empty($this->data[$this->alias]['is_active'])) {
$this->updateAll(
array('is_active' => 0),
array(
'id !=' => $this->id,
'is_active' => 1
)
);
}
}
I.e. after successfully saving a record, if it is active disable all the others.
Note: be sure to use the same method signature as the parent class. It varies depending on which version of CakePHP you are using.
You can write before save method like
public function beforeSave($options=array()){
if (!empty($this->data[$this->alias]['is_active'])) {
$this->data[$this->alias]['is_active'] = 0;
}
return true;
}