Hi all i am trying to create a campaign. In the process of campaign i will assign certain products to that campaign. So i have to insert details after post campaign creation into two tables one is campaigns and another one is campaignsproducts. So i created two models for each of them on the same names.
I am trying to insert records into both tables on post action using save method. I am able to insert into campaigns but when it comes to campaignsproducts it says campaigns_products table not exists.
In my db my table name was CampaignsProducts. Please help where i am going wrong. Please find my migration, model and post action code below.
<?php
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateCamapignproductsTable extends Migration {
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('campaignproducts', function(Blueprint $table)
{
$table->increments('id');
$table->integer('campaign_id')->unsigned();
$table->integer('product_id')->unsigned();
$table->decimal('product_sell_cost', 10, 2);
$table->timestamps();
});
Schema::table('campaignproducts', function($table) {
$table->foreign('campaign_id')->references('id')->on('campaigns');
$table->foreign('product_id')->references('id')->on('products');
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::drop('campaignproducts');
}
}
Model CampaignProducts.php
<?php
class CampaignProducts extends Eloquent {
public function camapigns(){
return $this->hasMany('Campaign');
}
public function products(){
return $this->hasMany('Product');
}
}
Post action in controller
public function postCampaign()
{
//validation rules for create product
$rules = array(
'campaign_name' => 'required|min:2',
'campaign_description' => 'required|min:2',
'campaign_startdate' => 'required|date_format:"Y-m-d"',
'campaign_enddate' => 'required|date_format:"Y-m-d"',
'campaign_urlname' => 'required|between:4,20',
'campaign_target' => 'required|integer|min:1',
'user_id' => 'required|integer|min:1'
);
$validator = Validator::make(Input::all(), $rules);
//procee the validation rules
if($validator->fails()) {
return Redirect::to('products/newcampaign')
->withErrors($validator)
->withInput();
} else {
echo "<pre>";
print_r(Input::all());
//store category data
$campaign = new Campaign;
$campaign->campaign_name = Input::get('campaign_name');
$campaign->campaign_description = Input::get('campaign_description');
$campaign->campaign_startdate = Input::get('campaign_startdate');
$campaign->campaign_enddate = Input::get('campaign_enddate');
$campaign->campaign_urlname = Input::get('campaign_urlname');
$campaign->campaign_target = Input::get('campaign_target');
$campaign->user_id = Input::get('user_id');
$campaign_id = $campaign->save();
$campaign_products = Input::get('productid');
$campaignproducts = new CampaignProducts;
foreach($campaign_products as $key => $id)
{
$campaignproducts->product_id = $key;
$$campaignproducts->product_sell_cost = $id;
$campaignproducts->campaign_id = $campaign_id;
$campaignproducts->save();
}
//redirect
Session::flash('message', 'Successfully created campaign!');
return Redirect::to('campaigns');
}
}
Add this to your CampaignProducts model:
class CampaignProducts extends Eloquent {
protected $table = 'campaignsproducts';
...
Or the other option is to change your table name when you create it instead:
Schema::create('campaign_products', function(Blueprint $table)
Related
I know the question has been responded many times, but for some reason I couldn't make it work for my tables, no matter what, and I don't understand why.
I've been trying this for like 4 hours and I couldn't get it done right.
So here are my functions from two models:
ConducatorDoctorat
public function materii()
{
return $this->belongsToMany('App\DomeniuDoctorat', 'profesor_domeniu', 'domeniu_id', 'profesor_id');
}
DomeniuDoctorat
public function materii()
{
return $this->belongsToMany('App\ConducatorDoctorat', 'profesor_domeniu', 'profesor_id', 'domeniu_id');
}
and profesor_domeniu schema:
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class ProfesorDomeniu extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('profesor_domeniu', function (Blueprint $table) {
$table->unsignedBigInteger('profesor_id');
$table->unsignedBigInteger('domeniu_id');
$table->foreign('profesor_id')
->references('id')->on('conducatori_doctorat')
->onDelete('cascade');
$table->foreign('domeniu_id')
->references('id')->on('domenii_doctorat')
->onDelete('cascade');
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::dropIfExists('profesor_domeniu');
}
}
In my controller, I tried so many ways to do it, for example, like this:
public function edit($id)
{
$materii = ConducatorDoctorat::findOrFail($id)->materii()->pluck('domeniu_id');
return view('admin.conducatori_doctorat.edit')->with([
'materii' => $materii
]);
}
but it still doesn't work.
With the given $id, I want to retrieve all the data from profesor_domeniu where profesor_id == $id.
That's all, but I can't get it.
How can this be done and why doesn't my approach work?
//edit for clarity:
conducator_doctorat is where the professors are stored and domenii_doctorat is where their fields are stored.
In profesor_domeniu, I store what each professor teaches, by linking an id from conducatori_doctorat to an id of a field from domenii_doctorat.
//edit2:
materii() means the fields they teach.
//edit3:
My many-to-many relationship with some data added into the pivot table profesor_domeniu.
eager load your relationship on your model :
public function edit($id)
{
$conducatorDoctorat = ConducatorDoctorat::with('materii')->findOrFail($id);
$materii = $conducatorDoctorat->materii;
return view('admin.conducatori_doctorat.edit')->with([
'materii' => $materii
]);
}
you can also request only your materii related to your conducatorDoctorat :
public function edit($id)
{
$materii = DomeniuDoctorat::whereHas('materii', function($query) use ($id){
$query->where('id', $id);
})->get();
return view('admin.conducatori_doctorat.edit')->with([
'materii' => $materii
]);
}
I have two tables that I want to join in the controller - thought_journal_entries and emotions. A thought journal entry can contain many emotions and the foreign key in the thought_journal_entries table is em_id.
This is an example thought journal entry where the user selected emotions with id 1, 3, 5
This is the emotions table
This is the method I'm using to store data within my thought_journal_entries table
public function store(Request $request)
{
$this->validate($request, [
'thought_entry' => 'required'
]);
$entry = new ThoughtJournalEntry;
$entry->user_id = auth()->user()->id;
$entry['entry_date'] = date('Y-m-d H:i');
$entry->thought = $request->input('thought_entry');
$entry->em_id = $request->has('emotions') ? $request->get('emotions') : [];
$entry->tt_id = $request->has('thinking_traps') ? $request->get('thinking_traps') : [];
$entry->balanced_thought = $request->input('balanced_thought');
$entry->save();
return redirect('/dashboard');
}
In your example em_id column it's not a foreign key, it's a string column as I see.
Therefore, you can't execute a JOIN query for these tables. In your case, I can recommend create a third table thought_journal_entry_emotions.
Here example of code for migration file 2020_02_29_143059_create_thought_journal_entry_emotions_table.php:
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateThoughtJournalEntryEmotionsTable extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('thought_journal_entry_emotions', function (Blueprint $table) {
$table->integer('thought_journal_entry_id')->unsigned();
$table->integer('emotion_id')->unsigned();
$table->foreign('thought_journal_entry_id')
->references('id')
->on('thought_journal_entries')
->onUpdate('cascade')
->onDelete('cascade');
$table->foreign('emotion_id')
->references('id')
->on('emotions')
->onUpdate('cascade')
->onDelete('cascade');
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::dropIfExists('thought_journal_entry_emotions');
}
}
Then you have to add relationships to your models Emotion and ThoughtJournalEntry.
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Emotion extends Model
{
public function thoughtJournalEntries() {
return $this->belongsToMany(ThoughtJournalEntry::class, 'thought_journal_entry_emotions',
'emotion_id', 'thought_journal_entry_id');
}
}
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class ThoughtJournalEntry extends Model
{
public function emotions() {
return $this->belongsToMany(Emotion::class, 'thought_journal_entry_emotions',
'thought_journal_entry_id', 'emotion_id');
}
}
After that you can attach Emotions to ThoughtJournalEntry in your controller using this code:
$thoughtJournalEntry = ThoughtJournalEntry::find(1);
$emotion1 = Emotion::find(1);
$emotion2 = Emotion::find(2);
$emotion3 = Emotion::find(3);
$thoughtJournalEntry->emotions()->sync([$emotion1->id, $emotion2->id, $emotion3->id]);
And finally you can load your ThoughtJournalEntry with Emotions in your controller using this code:
$thoughtJournalEntry = ThoughtJournalEntry::with('emotions')->find(1);
dd($thoughtJournalEntry);
If you wanna validate and store Emotions relations you must update your store() method (add new validate rule and sync()).
Here example:
public function store(Request $request)
{
$this->validate($request, [
'thought_entry' => 'required',
'emotions' => 'array|max:3',
'emotions.*' => 'exists:emotions,id'
]);
$entry = new ThoughtJournalEntry;
$entry->user_id = auth()->user()->id;
$entry['entry_date'] = date('Y-m-d H:i');
$entry->thought = $request->input('thought_entry');
$entry->tt_id = $request->has('thinking_traps') ? $request->get('thinking_traps') : [];
$entry->balanced_thought = $request->input('balanced_thought');
$entry->save();
$entry->emotions()->sync($request->get('emotions'));
return redirect('/dashboard');
}
Joining the table will be a little trickier since the reference value isn't present.
But if you trying to get the names of emotions from using the id stored in the array.
You will need to first save the emotions array in a variable.
$em = ["1","3","5"]
$em = ["1","3","5"];
foreach ($em as $e) {
$emotions = Emotions::find($e * 1); //am using * 1 just make sure its int
$emotions->em_name;
}
I hope that helps.
this should done using Many to Many Relationships, you are using string to store array(thats not mysql way). (but looks like you are going to save space in 'thought_journal_entries')
you can use like this:
$journal_entries = thought_journal_entries::find(1);
$icon_ids = json_decode($journal_entries->em_id); // if this column is json
$emocions = emotions::whereIn('id', $icon_ids)->get();
but this executing two quarries, that may affect db and server performance
This question concerns Laravel Nova 2.5.
I have a User (Nova) resource class that contains a 'file' field.
I don't want the file path to be stored in my users DB table, but in a general 'files' DB table.
I found this code snippet in the Laraval Nova documentation that explains how to store the file path in the related table. But I'm not sure how I can set the FK field (file_id) in my users table (As now this field remains NULL, when storing the user resource via Nova). The snippet I found comes from:
https://nova.laravel.com/docs/2.0/resources/file-fields.html#customizing-file-storage
use Illuminate\Http\Request;
File::make('Attachment')
->store(function (Request $request, $model) {
return function () use ($resource, $request) {
$media = $resource->media()->updateOrCreate([], [
'path'=> $request->file('attachment')->store('/path', 'public')
]);
};
});
My users table looks like this:
id (prim key)
file_id (unsigned int)
username (varchar: 255)
email (varchar: 255)
created_at (datetime)
updated_at (datetime)
My files table looks like this:
id (prim key)
original_name (varchar: 255)
generated_name (varchar: 255)
created_at (datetime)
updated_at (datetime)
Thanks.
Instead of naming “files” table, I choose the name “items”, because the Nova resource of table will be same name with “use Laravel\Nova\Fields\File;”.
The basic solution for your problem:
// database\migrations\2019_11_01_103838_create_items_table.php
Schema::create('items', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('original_name',255);
$table->string('generated_name',255);
$table->timestamps();
});
// database\migrations\2019_11_01_104145_add_column_item_id_to_users_table.php
Schema::table('users', function (Blueprint $table) {
$table->unsignedBigInteger('item_id')->nullable();
$table->foreign('item_id')->references('id')->on('items');
});
// app\Nova\User.php
public function fields(Request $request)
{
return [
ID::make()->sortable(),
Gravatar::make(),
Text::make('Name')
->sortable()
->rules('required', 'max:255'),
Text::make('Email')
->sortable()
->rules('required', 'email', 'max:254')
->creationRules('unique:users,email')
->updateRules('unique:users,email,{{resourceId}}'),
Password::make('Password')
->onlyOnForms()
->creationRules('required', 'string', 'min:8')
->updateRules('nullable', 'string', 'min:8'),
File::make('Item file')
->store(function (Request $request, $model) {
$oldName = $request->item_file->getClientOriginalName();
$newName = 'user_file_'.$oldName;
// Check file of user is exist or not
$user = \App\User::where('email',$request->email)->first();
if(!$user){
$item = new \App\Item;
$item->original_name = $oldName;
$item->generated_name = $newName;
$item->save();
$model['item_id'] = $item->id;
}else{
$item = \App\Item::find($user->item_id);
if(!$item){
$item = new \App\Item;
$item->original_name = $oldName;
$item->generated_name = $newName;
$item->save();
$model['item_id'] = $item->id;
}else{
$item->original_name = $oldName;
$item->generated_name = $newName;
$item->save();
}
}
// return $newName;
$request->item_file->storeAs('public',$newName);
})
->onlyOnForms(),
Text::make('Item File Id','item_id')->exceptOnForms()
];
}
// app\Observers\UserObserver.php = To delete the variable $model['item_file'] generate by File::make('Item file') in field User Nova resources.
<?php
namespace App\Observers;
use App\User;
class UserObserver
{
public function saving(User $user)
{
unset($user->item_file);
}
}
// app\Providers\AppServiceProvider.php = To register the UserObserver
<?php
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
use App\Observers\UserObserver;
use App\User;
class AppServiceProvider extends ServiceProvider
{
/**
* Register any application services.
*
* #return void
*/
public function register()
{
//
}
/**
* Bootstrap any application services.
*
* #return void
*/
public function boot()
{
User::observe(UserObserver::class);
}
}
I am trying to create a many to many relationship between this profile and an availability table but within my test i keep getting call to a undefined method on availability in the test.
This is the controller function
/**
* Creates association between availability and podcast profile
*
* #param array $availabilities
*/
private function associateAvailability(array $availabilities)
{
$this->podcastProfile->availability()->sync(
array_map(function ($availability) {
$availabilityModel = Availability::where('availability', '=', $availability)->first();
return $availabilityModel->id;
}, $availabilities)
);
}
This is the method in the podcast profile model
/**
* Defines many-to-many relationship between podcasts and availabilities
*/
public function availability(): BelongsToMany
{
return $this->belongsToMany(
'App\Models\Availability',
'podcast_availability',
'podcast_profile_id',
'availability_id'
);
}
This is the test for the method
/**
* #test
*/
public function it_should_create_availability_relationship()
{
$this->handlePostRequestToController();
$this->assertTrue($this->user->podcastProfile->availability()->exists());
$this->checkAvailability($this->requestData['availability']);
}
this is the check availability method inserted into the test
/**
* Check database
*
* #param $availabilities
*/
private function checkAvailability($availabilities): void
{
foreach ($availabilities as $availability) {
$availabilityModel = Availability::where('availability', '=', $availability)
->first();
$this->assertDatabaseHas('podcast_availability', [
'podcast_profile_id' => $this->user->podcastProfile->id,
'availability_id' => $availabilityModel->id
]);
}
}
this is the error
1) Tests\Feature\PodcastProfileControllerTest::it_should_create_availability_relationship
BadMethodCallException: Method Illuminate\Database\Eloquent\Collection::availability does not exist.
If your trying to make a Many to Many relationship base on Laravel Many to Many Relationship.
Here's how you do it. You need to have to 2 models and 3 migrations.
FIRST
Your model should look like this:
Profile Model
protected $guarded = [];
public function availabilities() {
return $this->belongsToMany(Availability::class);
}
Note: I use availabilities because it is in a many to many relationship so its a better naming convention.
Availability Model
protected $guarded = [];
public function profiles() {
return $this->belongsToMany(Profile::class);
}
SECOND
Your migration should be like this:
Profile Migration
Schema::create('profiles', function (Blueprint $table) {
$table->bigIncrements('id');
...
$table->timestamps();
});
Availability Migration
Schema::create('availabilities', function (Blueprint $table) {
$table->bigIncrements('id');
...
$table->timestamps();
});
Availability And Profiles Migration
Schema::create('availability_profile', function (Blueprint $table) {
$table->bigIncrements('id');
$table->unsignedBigInteger('availability_id');
$table->unsignedBigInteger('profile_id');
$table->timestamps();
});
Note: I use the availability_profile naming convention in alphabetical order
INFO
You can generate this migration using artisan command like this php artisan make:migration create_availability_profile_table --create=availability_profile
LAST
In you controller you can assign the profile to availability
Controller
Assuming you have record on your database.
public function generateAvailability() {
$profile = Profile::firstOrFail(1);
$role = Role::firstOrFail(1);
$profile->availabilities()->attach($role->id);
dd(profile->availabilities);
}
Note: I use dd(dump and die) to check the record
You can also see this reference and this
[SOLVED]I'm facing problems trying to fix the following error.
SQLSTATE[42S22]: Column not found: 1054 Unknown column 'testimonial_by' in 'field list' (SQL: insert into testimonials (testimonial_by, testimonial_text, updated_at, created_at) values (John Doe, Lorem Ipsum is really lit!, 2019-10-02 20:37:53, 2019-10-02 20:37:53))
I have added my code related to 'testimonials' below.
app/Testimonial.php
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Testimonial extends Model
{
public $guarded = [];
public function allTestimonials()
{
return self::all();
}
}
TestimonialController.php
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Testimonial;
class TestimonialController extends Controller
{
public function index()
{
$testimonials = Testimonial::all();
return view('dashboard.testimonials.index')->withTestimonials($testimonials);
}
public function create()
{
return view('dashboard.testimonials.create');
}
public function store(Request $request)
{
$request->validate(['testimonial_text'=>'required']);
$testimonial = Testimonial::create($request->all());
if($testimonial)
{
$this->success('Testimonial added successfully');
}
else
{
$this->error();
}
return redirect()->back();
}
public function edit(Testimonial $testimonial)
{
return view('dashboard.testimonials.edit')->withTestimonial($testimonial);
}
public function update(Testimonial $testimonial,Request $request)
{
if($testimonial->update($request->all()))
{
$this->success('Testimonial Updated Successfully');
}
else
{
$this->error();
}
return redirect()->route('dashboard.testimonials.index');
}
public function destroy(Testimonial $testimonial)
{
if($testimonial->delete())
{
$this->success('Testimonial Deleted Successfully');
}
else
{
$this->error();
}
return redirect()->back();
}
}
migration
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateTestimonialsTable extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('testimonials', function (Blueprint $table) {
$table->bigIncrements('id');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::dropIfExists('testimonials');
}
}
I can't seem to find where I'm going wrong. Thank you for your time and support.
You need to add those columns to your migration:
Schema::create('testimonials', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('testimonial_by'); // or $table->integer('testimonial_by'); if a user ID
$table->string('testimonial_text');
$table->timestamps();
});
it looks like you have fields with names (testimonial_by and testimonial_text) in the form. But they are absent in migration. Can you open your DB and look at columns?
If they are absent - add to migration
$table->string('testimonial_by'); //or integet
$table->string('testimonial_text');
PS. you may need in the future in model protected $fillable = [array with column names for filling];
Add these lines to your migration..
Schema::create('testimonials', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('testimonial_by',200);
$table->text('testimonial_text');
$table->timestamps();
});
In your model add these fields as fillable
class Testimonial extends Model
{
public $guarded = [];
public $timestamps = true;
protected $fillable = ['testimonial_text','testimonial_by'];
public function allTestimonials()
{
return self::all();
}
}
Create table entry using required fields only..
$testimonial = Testimonial::create(
'testimonial_by' => $request->input('testimonial_by'), //put current user name
'testimonial_text' => $request->input('testimonial_text')
);
Remove the migration file entry from migrations table and run the php artisan:migrate command.It will create testimonials table with updated columns.
Thank you all for your help. I found out where I was going wrong.
I added the following likes to my migrations
$table->string('testimonial_by');
$table->string('testimonial_text');
Then i tried running php artisan migrate but I still got the same error.
So, I went and created the columns on my own and simple ran the project and it worked.