I have a basic module ready with controller and view working perfectly. Now, I am trying to initiate model in order to save data using custom model in table containing attributes (question Title, Question). Basically, what steps I should proceed in order to save data through model in a custom table ?
How should I do it, any help would be greatly appreacited.
I have below code in my action file :
class Post extends \Magento\Framework\App\Action\Action
{
protected $_objectManager;
public function __construct(\Magento\Framework\ObjectManagerInterface $objectManager)
{
$this->_objectManager = $objectManager;
}
public function execute()
{
$post = $this->getRequest()->getPostValue();
$model = $this->_objectManager->create('Chirag\Mygrid\Model\Question');
$model->setData('question_title', $post['question_title']);
$model->setData('question', $post['question']);
$model->save();
}
}
<?php
/**
* Copyright © 2015 Magento. All rights reserved.
* See COPYING.txt for license details.
*/
namespace Chirag\Mygrid\Model;
class Question extends \Magento\Framework\Model\AbstractModel
{
/**
* Initialize resource model
*
* #return void
*/
protected function _construct()
{
$this->_init('Chirag\Mygrid\Model\Resource\Question');
}
}
<?php
/**
* Copyright © 2015 Magento. All rights reserved.
* See COPYING.txt for license details.
*/
namespace Chirag\Mygrid\Model\Resource;
class Question extends \Magento\Framework\Model\Resource\Db\AbstractDb
{
/**
* Initialize resource model
*
* #return void
*/
protected function _construct()
{
$this->_init('questions_and_answers', 'question_id');
}
}
<?php
/**
* Copyright © 2015 Magento. All rights reserved.
* See COPYING.txt for license details.
*/
namespace Chirag\Mygrid\Model\Resource\Question;
class Collection extends \Magento\Framework\Model\Resource\Db\Collection\AbstractCollection
{
protected function _construct()
{
$this->_init('Chirag\Mygrid\Model\Question', 'Chirag\Mygrid\Model\Resource\Question');
$this->_map['fields']['page_id'] = 'main_table.page_id';
}
/**
* Prepare page's statuses.
* Available event cms_page_get_available_statuses to customize statuses.
*
* #return array
*/
public function getAvailableStatuses()
{
return [self::STATUS_ENABLED => __('Enabled'), self::STATUS_DISABLED => __('Disabled')];
}
}
1st Edit:
I had successfully completed this and have uploaded the whole setup to Git, please find below URL in case you want to check it out :
FAQ with custom grid extension in Magento 2
You can save Data like this way in Magento 2:
$question = $this->_objectManager->create('Ecom\HelloWorld\Model\Question');
$question->setTitle('Simple Question');
$question->setDescription('Question Description');
$question->save();
this is the code that you will add in your particular action
Updated Answer
Add your question model as follows:
namespace Chirag\Mygrid\Model;
class Question extends \Magento\Framework\Model\AbstractModel
{
public function __construct(
\Magento\Framework\Model\Context $context,
\Magento\Framework\Registry $registry,
\Magento\Framework\Model\Resource\AbstractResource $resource = null,
\Magento\Framework\Data\Collection\AbstractDb $resourceCollection = null,
array $data = []
) {
parent::__construct($context, $registry, $resource, $resourceCollection, $data);
}
public function _construct()
{
$this->_init('Chirag\Mygrid\Model\Resource\Question');
}
}
Also please flush cache as well.
Please follow here as well: In magento 2 what is the correct way for getModel?
Related
I'm trying to convert a build Nova tool to a resource tool. I've tried to change my Tool to extend ResourceTool instead of Tool and add the resource tool to the Resource in the fields, but it's not showing up. I also changed the code of ToolServiceProvider to match that of a ResourceTool but it does not work unfortunately.
I've searched the internet but I seem to be the only one having this issue, anyone ever experienced this and know what to do? I'm not getting any error message, the resource tool just is not showing up.
Here is my code, I removed some of it for readability and confidentiality.
Product (Resource)
<?php
namespace App\Nova;
use confidentiality\SalesHistory\SalesHistory;
class Product extends Resource
{
/**
* Get the fields displayed by the resource.
*
* #param \Illuminate\Http\Request $request
* #return array
*/
public function fields(Request $request)
{
return [
ID::make()->sortable(),
SalesHistory::make(),
];
}
}
SalesHistory (Resource tool)
<?php
namespace confidentiality\SalesHistory;
use Laravel\Nova\ResourceTool;
class SalesHistory extends ResourceTool
{
/**
* Get the displayable name of the resource tool.
*
* #return string
*/
public function name()
{
return 'Sales History';
}
/**
* Get the component name for the resource tool.
*
* #return string
*/
public function component()
{
return 'sales-history';
}
}
ToolServiceProvider (Resource Tool)
<?php
namespace confidentiality\SalesHistory;
use Laravel\Nova\Nova;
use Laravel\Nova\Events\ServingNova;
use Illuminate\Support\Facades\Route;
use Illuminate\Support\ServiceProvider;
class ToolServiceProvider extends ServiceProvider
{
/**
* Bootstrap any application services.
*
* #return void
*/
public function boot()
{
$this->app->booted(function () {
$this->routes();
});
Nova::serving(function (ServingNova $event) {
Nova::script('sales-history', __DIR__.'/../dist/js/tool.js');
Nova::style('sales-history', __DIR__.'/../dist/css/tool.css');
});
}
/**
* Register the tool's routes.
*
* #return void
*/
protected function routes()
{
if ($this->app->routesAreCached()) {
return;
}
Route::middleware(['nova'])
->prefix('nova-vendor/sales-history')
->group(__DIR__.'/../routes/api.php');
}
/**
* Register any application services.
*
* #return void
*/
public function register()
{
//
}
}
I managed to fix it finally. I also had to change the tool.js file to match that of a Resource Tool.
Nova.booting((Vue, router, store) => {
Vue.component('sales-history', require('./components/Tool'))
})
Try this command from the root of project: composer update
Add id manually looks like this
{!! Form::text('email', null, ['id' => 'email', 'class' => 'active']) !!}
How to auto add id?
Any example to use macro?
Create your new FromBuilder Class :
class MyFormBuilder extends \Collective\Html\FormBuilder /** Original Form Builder*/{
// Override the text function
public function text($name, $value = null, $options = []){
// If the ID is not explicitly defined in the call
if(!isset($options['id'])){
// Set ID equal to the name
$options['id'] = $name;
}
// Call the original text function with the new ID set
parent::text($name,$value,$options);
}
}
Then Create a new Service Provider
<?php
namespace My\Provider\Space;
use Illuminate\Support\ServiceProvider;
class MyHtmlServiceProvider extends ServiceProvider
{
/**
* Indicates if loading of the provider is deferred.
*
* #var bool
*/
protected $defer = true;
/**
* Register the service provider.
*
* #return void
*/
public function register()
{
$this->registerHtmlBuilder();
$this->registerFormBuilder();
$this->app->alias('html', 'Collective\Html\HtmlBuilder');
$this->app->alias('form', 'My\Class\Space\MyFormBuilder');
}
/**
* Register the HTML builder instance.
*
* #return void
*/
protected function registerHtmlBuilder()
{
$this->app->singleton('html', function ($app) {
return new \Collective\Html\HtmlBuilder($app['url'], $app['view']);
});
}
/**
* Register the form builder instance.
*
* #return void
*/
protected function registerFormBuilder()
{
$this->app->singleton('form', function ($app) {
$form = new \My\Class\Space\MyFormBuilder($app['html'], $app['url'], $app['view'], $app['session.store']->getToken());
return $form->setSessionStore($app['session.store']);
});
}
/**
* Get the services provided by the provider.
*
* #return array
*/
public function provides()
{
return ['html', 'form', 'Collective\Html\HtmlBuilder', 'My\Class\Space\FormBuilder'];
}
}
Then update your config/app.php file and do:
Remove The old \Collective\Html\HtmlServiceProvider::class from the service providers array
Add Your new Service provider in it's place.
A basic explanation of what this does:
A. You move the service provider for the HTML helpers to your own service provider where you register your MyBuilder
B. Next time you call \Form that service provider will point it to your builder.
Check out the vendor files for collective to make sure you get all the variables in the function definitions.
Just filter out any namespace errors etc. as I have not completely tested them all.
I am trying to create one observer for apply additional filters to product collection.
So I use magento 2 event :catalog_product_collection_load_after
Observer code is :
public function execute(\Magento\Framework\Event\Observer $observer)
{
$collection = $observer->getEvent()->getCollection();
$collection->addAttributeToFilter('size',10);
return $this;
}
But above code working fine with product collection, but showing wrong pagination and product count
Same happen for layer navigation.
Is there any solution for that?
Try this:
namespace Vendor\Module\Observer;
use Magento\Framework\Event\ObserverInterface;
use Magento\Catalog\Model\Layer\Resolver as LayerResolver;
class CatalogProductCollectionLoadAfter implements ObserverInterface
{
/**
* #var \Magento\Catalog\Model\Layer\Category
*/
protected $catalogLayer;
/**
* #param LayerResolver $layerResolver,
*/
public function __construct(
LayerResolver $layerResolver
) {
$this->catalogLayer = $layerResolver->get();
}
public function execute(\Magento\Framework\Event\Observer $observer)
{
// Get selected filters
$layer = $this->catalogLayer;
$activeFilters = $layer->getState()->getFilters();
}
}
I’m new to Laravel 5. I tried to create Customer model in my Models folder. I created both CustomerController and Customer via php artisan make:... and now I get the error:
FatalErrorException in CustomerController.php line 30: Class 'App\Http\Controllers\Cusomter' not found.
My Customer model:
<?php namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Customer extends Model {
//
protected $table = 'Customer';
protected $primaryKey = 'CID';
// protected $fillable = [
// 'Name',
// 'Gender',
// 'Address',
// 'DiscountPercent',
// 'Email',
// 'Phone'
// ];
}
My CustomerController:
<?php namespace App\Http\Controllers;
use App\Http\Requests;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use App\Models\Customer;
class CustomerController extends Controller {
/**
* Create a new controller instance.
*
* #return void
*/
public function __construct()
{
$this->middleware('guest');
}
/**
* Display a listing of the resource.
*
* #return Response
*/
public function index()
{
//
$customers = Customer::all();
return View::make('Customer.home',compact('customers'));
// return View('Customer.home');
}
/**
* Show the form for creating a new resource.
*
* #return Response
*/
public function create()
{
//
}
/**
* Store a newly created resource in storage.
*
* #return Response
*/
public function store()
{
//
}
/**
* Display the specified resource.
*
* #param int $id
* #return Response
*/
public function show($id)
{
//
}
/**
* Show the form for editing the specified resource.
*
* #param int $id
* #return Response
*/
public function edit($id)
{
//
}
/**
* Update the specified resource in storage.
*
* #param int $id
* #return Response
*/
public function update($id)
{
//
}
/**
* Remove the specified resource from storage.
*
* #param int $id
* #return Response
*/
public function destroy($id)
{
//
}
}
I dont know what i was doing anything wrong. Is there any help. I also did some search on Internet and i know its about namespace. Is there any ebook or documents for me to understand how namespace works, how to use and do i need to declare before using it
You’ve spelt “Customer” wrong in your index action.
You should add autoload classmap in composer.json
"autoload": {
"classmap": [
"database",
"app/Models"
],
"psr-4": {
"App\\": "app/"
}
},
update composer
I'm attempting to add what I hope is a simple voting module to posts and comments. A "Connection" is a type of post in my application. Users can vote up or down a Connection, or a Comment.
The issue I'm running into is when I attempt to attach a vote to a Connection. I receive this error: Class name must be a valid object or a string.
Here's the line of code in question:
$voteToCast = $vote->voteable()->associate($voteable);
I am certain the $voteable var is an instance of an Ardent/Eloquent model, so I can only presume the error lies within the way I am namespacing my models, or some pathetic typo I am too blind to see. Any help would be greatly appreciated.
Thanks!
Connection Model (type of post):
...
public function votes()
{
return $this->morphMany('Acme\Votes\Vote', 'voteable');
}
And the Votes Model:
/* Votes Model */
namespace Acme\Votes;
use Illuminate\Database\Eloquent\Model;
use LaravelBook\Ardent\Ardent;
class Vote extends Ardent {
protected $table = 'votes';
protected $fillable = [
'value',
'votable_id',
'voteable_type'
];
/**
* Establish the polymorphic relationship
*
* #return \Illuminate\Database\Eloquent\Relations\BelongsTo
*/
public function voteable()
{
return $this->morphTo();
}
public function users()
{
return $this->belongsTo('Acme\\Users\\User');
}
/**
* Vote the item up
*
* #param Model $voteable
* #return mixed
*/
public static function up(Model $voteable)
{
return (new static)->cast($voteable, 1);
}
/**
* Vote the item down
*
* #param Model $voteable
* #return mixed
*/
public static function down(Model $voteable)
{
return (new static)->cast($voteable, -1);
}
/**
* Execute the vote
*
* #param Model $voteable
* #param int $value
* #return bool
*/
protected function cast(Model $voteable, $value = 1)
{
if (!$voteable->exists) return false;
$vote = new static;
$vote->value = $value;
$voteToCast = $vote->voteable()->associate($voteable);
$voteToCast->save();
}
/**
* Restrict the votes so the absolute value is 1
*
* #param $value
*/
public function setValueAttribute($value)
{
$this->attributes['value'] = ($value == -1) ? -1 : 1;
}
}
Votes Controller:
...
public function cast($connection)
{
$voteable = Connection::findOrFail($connection);
if (Input::get('value' < 1)){
return Vote::down($voteable);
}
return Vote::up($voteable);
}
After some more troubleshooting, this appears to be an issue with the way Ardent handles relationships. I was able to use Eloquent on my Vote model instead of Ardent and the voting mechanism now works flawlessly.