I have following code in my controller:
$listproduct=Yii::app()->db->createCommand()
->select('product')
->from('product_form')
->where('product_name=:product_name and type=:type', array(':product_name'=>'HP', ':type'=>$gettype ))
->queryRow();
$gettype is responsible for retrieving types of the product. (e.g if the name of the product is HP and type($gettype) is PC, it will display the HP product where type is PC). I could not realize this function without createCommand. How can I do it?
You could use CActiveRecord features
assuming you have a CActiveRecode model class named
class ProductForm extends CActiveRecord
{
/**
* #return string the associated database table name
*/
public function tableName()
{
.......
you could use
For obtain all the models you can use findAllByAttributes()
$listProduct= ProductForm::model()->
findAllByAttributes(array('product_name'=>'HP', 'type' =>$gettype ));
for obtain a single model you can use findByAttributes()
you can take a look at http://www.yiiframework.com/doc/guide/1.1/en/database.ar
Related
hey everybody is it technically possible to set data in an extra column in the pivot table?
my database is like
products
sellers
id
id
title
name
brand_id
and...
prodduct_sellrs
id
product_id
seller_id
price
and I want to Seed my database with factory Faker data and here is my code in my seeder (I've already made the ProductFactory and.... )
Product::factory()
->foruser()
->hasCategories()
->hasTags()
->hassellers()
->forBrand()
->forAttributeSet()
->create();
but when I run it I get this error
General error: 1364 Field 'price' doesn't have a default value
which is truly right but anybody can help how I can define value for price in the pivot table?
You can use factory callbacks
Factory callbacks - Laravel
After create your Product, you can create data for your relational tabble
namespace Database\Factories;
use App\Models\Product;
use Illuminate\Database\Eloquent\Factories\Factory;
use Illuminate\Support\Str;
class ProductFactory extends Factory
{
/**
* The name of the factory's corresponding model.
*
* #var string
*/
protected $model = Product::class;
/**
* Configure the model factory.
*
* #return $this
*/
public function configure()
{
return $this->afterCreating(function (Product $product) {
$product->sellers()->save(factory(App\ProductSeller::class)->make());
});
}
// ...
}
I realized my answer If anyone wanted to use
Product::factory()
->foruser()
->hasCategories()
->hasAttached(
Seller::factory()->count(10),
['price'=>423432432]
)
and it solved, here it is
What I need to do is extend all of the functionality of the Spatie permissions package Role model, but use a different table for the derived model.
Right now I have a model SubscriptionPackage that I want to emulate the behavior of a Role such that it can be assigned permissions and in turn this model can be assigned to users. But I wanna keep the Role model intact too.
I have tried extending Yes, but when I create a new SubscriptionPackage, the new record is created in the roles tables instead of subscription_packages table despite specifying the table in my derived Model. As shown below
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use App\Models\Permission; // This extends from Spatie\Permission\Models\Permission
use Spatie\Permission\Models\Role as SpatieRole;
class SubscriptionPackage extends SpatieRole
{
//
protected $guarded = ['id'];
protected $table = 'subscription_packages';
/**
* The permissions that belong to the package.
*/
public function packagePermissions()
{
return $this->belongsToMany(Permission::class);
}
}
With the code above I expect when I create a new SubscriptionPackage, the record should be inserted into the subscription_packages table but in this case it goes to the roles table.
Any pointers on how to go about this will be highly appreciated.
If you have a look at the Role source code you will this inside the __construct method:
public function __construct(array $attributes = [])
{
$attributes['guard_name'] = $attributes['guard_name'] ?? config('auth.defaults.guard');
parent::__construct($attributes);
$this->setTable(config('permission.table_names.roles')); // <-- HERE IS THE PROBLEM!
}
So, if you want that your SubscriptionPackage to write its records in the right table you have to override this behaviour like this:
public function __construct(array $attributes = [])
{
parent::__construct($attributes)
$this->setTable('your_table_name'); // <-- HERE THE SOLUTION!
}
I don't think you can. Spatie already have 5 tables and fetched data from those only. But still if you want to make the change you have make the changes with table and column name in the model
I have problem with custom shipmentable_type. My structure looks like this:
transfers:
id - integer
name - string
shipment:
id - integer
name - string
shipmentale:
shipment_id - integer
shipmentable_id - integer
shipmentabl_type - enum ( transfer, order, complaint, internet )
Now I have in my Transfer model realtion like this:
public function shipments()
{
return $this->morphToMany(Shipment::class, 'shipmentable');
}
The problem is, that to table shipmentable, to column shipmentable_type is going sth like this now: App/Models/Transfer, but I would like to force to be there 'transfer' in this case. Is it possible?
From the docs
By default, Laravel will use the fully qualified class name to store the type of the related model. However, you may wish to decouple your database from your application's internal structure. In that case, you may define a relationship "morph map" to instruct Eloquent to use a custom name for each model instead of the class name:
use Illuminate\Database\Eloquent\Relations\Relation;
Relation::morphMap([
'transfer' => 'App/Models/Transfer'
]);
You may register the morphMap in the boot function of your AppServiceProvider or create a separate service provider if you wish.
To set a value other than the model's fully qualified name in shipmentable_type, there is the Relation::morphMap() function.
Relation::morphMap([
'transfer' => 'App/Models/Transfer'
]);
This should be set in the AppServiceProvider or similar.
I've had this issue but unfortunately I had multiple models pointing at transfer with multiple locations. You can resolve them dynamically on your model:
class Transfers extends Model
{
/**
* Declare the class to get connect polymorphic relationships.
*
* #var string|null
*/
protected $morphClass = null;
/**
* Get the associated morph class.
*
* #return string|null
*/
public function getMorphClass()
{
return $this->morphClass ?: static::class;
}
public function shipments()
{
$this->morphClass = 'transfer';
return $this->morphToMany(Shipment::class, 'shipmentable');
}
// ...
}
in my model i have
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Page extends Model
{
//
}
in my controller i can say Page:all() and get all the rows from pages table
but i dont see any connection between Page model and pages table in the database
does it just guess table name based on the model name (lower case with extra s at the end ) or it's mentioned somewhere else ?
As you can see in the docs, this is the magic of Laravel :-)
https://laravel.com/docs/5.2/eloquent#defining-models (see Table Names)
If you want, you can set another name manually by user the following
protected $table = 'my_table_name';
And to go a bit further, this is how Laravel gets the table name in the base Model you can found at /vendor/laravel/framework/src/Illuminate/Database/Eloquent/Model.php
/**
* Get the table associated with the model.
*
* #return string
*/
public function getTable()
{
if (isset($this->table)) {
return $this->table;
}
return str_replace('\\', '', Str::snake(Str::plural(class_basename($this))));
}
You can specify the table by putting the below code into your model
protected $table = 'your table name';
Otherwise, it takes a table name as a plural form of the model.
For example, if your model name Product then by default it connects the table named 'products'.
So if your table name is not different then no need to configure it. It's will connect automatically
By default, it takes the "snake case" of the class name used in the model. Also, add a final "s" to make the plural.
You can also define a custom name by adding the variable
protected $table = 'my_table_name';
in the model class.
For instance:
namespace App;
use Illuminate\Database\Eloquent\Model;
class Flight extends Model
{
/**
* The table associated with the model.
*
* #var string
*/
protected $table = 'my_flights';
}
I have this Laravel/OctoberCMS Model to interface with my ExchangeModel.
It's a one sided relationship with my ExchangeModel.
Currently it stores in the Customer database table via ExchangeModel.id. But i'd like it to store as ExchangeModel.currencyISO, which is a 3 letter country code.
What do I need to setup in the relation to get laravel to store it via the other field I try to define via otherKey or key instead of the primaryKey(id)?
<?php namespace PhunTime\Client\Models;
use Model;
/**
* Customer Model
*/
class Customer extends Model {
/**
* #var string The database table used by the model.
*/
public $table = 'CUSTOMER';
public $primaryKey = 'customerNumber';
/**
* #var array Relations
*/
public $belongsTo = ['currency' => ['PhunTime\ExchangeRate\Models\ExchangeModel',
'key' => 'currencyISO',// EUR,USD,YEN
'otherKey' => 'currencyISO'
]];
}
Clarification of the structure:
- Customer
- id
- name
- currency(varchar(3)) <-- relation
- ExchangeModel
- id
- currencyISO
Currently the ExchangeModel.id gets stored in Customer.currency
I want ExchangeModel.currencyISO to be stored in Customer.currency
Customer.currency is already a varchar field suitable to accept it.
Currently if I specify type:relation in fields.yaml it stores it by ExchangeModel.id no matter what I specify how it should store it. use of otherKey, foreignKey, key, nothing helps changing octobers mind.
Currently i'm using a type: dropdown that i populate via getcurrencyOptions() but in my feeling this is a less than ideal situation.