create crud doesnt work in yii2 - web

i make a simple CRUD in yii2 backend from table name "Guru",i already make models with the same table and make the CRUD but when i try to Create new data from the Create function,the data doesnt saved in database at all,i already make the code similar with the frontend and change the namespace but it didnt work at all in backend.
here is my backend "Guru" models code
<?php
namespace backend\models;
use Yii;
class Guru extends \yii\db\ActiveRecord
{
/**
* #inheritdoc
*/
public static function tableName()
{
return 'guru';
}
/**
* #inheritdoc
*/
public function rules()
{
return [
[['nip', 'nama_guru', 'ttl', 'jenis_kelamin', 'alamat', 'telp', 'agama', 'jabatan', 'user', 'pass', 'role', 'tgl_create', 'update_create', 'mapel'], 'required'],
[['jenis_kelamin'], 'string'],
[['mapel'], 'integer'],
[['nip', 'telp', 'jabatan', 'user', 'pass'], 'string', 'max' => 20],
[['nama_guru', 'ttl'], 'string', 'max' => 30],
[['alamat'], 'string', 'max' => 50],
[['agama', 'role', 'tgl_create', 'update_create'], 'string', 'max' => 10]
];
}
/**
* #inheritdoc
*/
public function attributeLabels()
{
return [
//'id_guru' => 'Id Guru',
'nip' => 'NIP',
'nama_guru' => 'Nama Guru',
'ttl' => 'Tempat Tanggal Lahir',
'jenis_kelamin' => 'Jenis Kelamin',
'alamat' => 'Alamat',
'telp' => 'No Telpon',
'agama' => 'Agama',
'jabatan' => 'Jabatan',
'user' => 'User',
'pass' => 'Pass',
'role' => 'Role',
'tgl_create' => 'Tgl Create',
'update_create' => 'Update Create',
'mapel' => 'Mata Pelajaran',
];
}
/**
* #return \yii\db\ActiveQuery
*/
public function getJadwalGuru() {
return $this->hasMany(Jadwal::className(), ['id_mapel'=>'mapel']);
}
public function getJadwal() {
return $this->hasMany(Jadwal::className(), ['nip'=>'id_guru']);
}
}
and this is my Controller code
namespace backend\controllers;
use Yii;
use backend\models\Guru;
use backend\models\GuruSearch;
use yii\web\Controller;
use yii\web\NotFoundHttpException;
use yii\filters\VerbFilter;
public function actionCreate()
{
$model = new Guru();
if ($model->load(Yii::$app->request->post()) && $model->save()) {
return $this->redirect(['view', 'id' => $model->id_guru]);
} else {
return $this->render('create', [
'model' => $model,
]);
}
}
i really dont know why it doesnt work when the other CRUD in backend and frontend is work.i'm new to this framework,please kindly help me.

Could be a validation problem,
you have a lot of required field and if one is missing the model is not saved.
For evaluate this situation try using save(false ) false mean without model validation. in this way :
public function actionCreate()
{
$model = new Guru();
if ($model->load(Yii::$app->request->post()) && $model->save(false)) {
return $this->redirect(['view', 'id' => $model->id_guru]);
} else {
return $this->render('create', [
'model' => $model,
]);
}
}
If with the param false the model is saved check selectively (by commenting) the rule that create problem with validation.

Related

How to get data from parent table in sequelize

I am using Sequelize dependency
I want to get data from the parent table, I have a table tblroute which is associated with routedetails .tblroute's id is the foreign key in routedetails
router.get('/bookingdetails', passengerMiddleware, (req, res) => {
tblBookingdetail.sync().then(() => {
tblBookingdetail.findAll({
where: {
passengerId: req.passenger.id
},
include: [
{
model: tblRoute,
as: 'route',
include: [
{
model: tblRouteDetails,
as: 'routedetails'
}
]
},
]
}).then(data => {
if (data && data.length > 0) {
return res.json(baseResponse.sendSuccess('data', data));
} else {
return res.json(baseResponse.sendError('data not found'));
}
});
})
})
it gives following error
Unhandled rejection SequelizeEagerLoadingError: tblRouteDetail is not associated to tblRoute!
Because you are trying to fetch result set without having a relationship define inside model tblRouteDetail.
Open your model tblRouteDetail and add a relationship between both table like below.
tblRoute.associate = function associate({ tblRouteDetail }) {
return tblRoute.hasOne(tblRouteDetail, {
foreignKey : 'tblroute_id'
});
};
It might help you to understand.

I can´t concatenate a label with string in symfony3

I can´t concatenate a label with string.
->add('originador', EntityType::class, array(
'label' => "app.label.x_originador".'*',
'class' => 'AppBundle:Usuario',
'em' => $options['entityManager'],
'query_builder' => function (EntityRepository $er) {
return $er->createQueryBuilder('u');
},
'placeholder' => '',
'required' => false,
))
In the part of 'label' => "app.label.x_originador".'*',
I need that the result be Originador*,because the label is for required value.
The result that I recieve is app.label.x_originador*
Please, help me to get
Originador* as result.
You can pass the translator service to your form type and translate then concatenate like this:
class MyFormType extends AbstractType
{
private $translator;
public function __construct(TranslatorInterface $translator)
{
$this->translator = $translator;
}
/**
* #param FormBuilderInterface $builder
* #param array $options
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('originador', EntityType::class, array(
'label' => $this->translator->trans('app.label.x_originador',[], 'domain').'*',
'class' => 'AppBundle:Usuario',
'em' => $options['entityManager'],
'query_builder' => function (EntityRepository $er) {
return $er->createQueryBuilder('u');
},
'placeholder' => '',
'required' => false,
));
}
}
juste replace "domain" with your translation domain.
EDIT: but yeah, the best solution is probably #ccKep's one

Yii2 searchmodel related model

As you can see I've gridview (from model called umumiy). And via id_nomi I'm showing nomi.rus (which means rus column from nomi model):
The issue here is I'm trying to make search from Nomi model via umumiy gridview. I'm trying to get values (with nomi.rus) via ajax. This is what I tried:
$model = new UmumiyModel();
$searchModel = new UmumiyModelSearch();
if (Yii::$app->request->isAjax){
$data = Yii::$app->request->post();
$searchModel->nomi->rus = $data['dori_nomi']; // search input value
$dataProvider = $searchModel->search(Yii::$app->request->queryParams);
return $this->renderPartial('sotish', [
'searchModel' => $searchModel,
'dataProvider' => $dataProvider,
'model' => $model,
]);
}
What am I doing wrong???
You can use a public member in NomiSearch model to store text value from "Id Nomi" input field of gridview.
So, in NomiSearch model:
class NomiSearch extends Nomi
{
public $nomiText;
public function rules()
{
return [
// ...
[['nomiText'], 'safe'],
];
}
public function search($params)
{
$query = Nomi::find();
// add conditions that should always apply here
$dataProvider = new ActiveDataProvider([
'query' => $query,
]);
$this->load($params);
if (!$this->validate()) {
// uncomment the following line if you do not want to return any records when validation fails
// $query->where('0=1');
return $dataProvider;
}
// grid filtering conditions
$query->andFilterWhere([
]);
if($this->nomiText!=null)
{
$query->andWhere(['IN', 'id_nomi', (new \yii\db\Query())->select('id')->from('nomi')->where(['like', 'nomi', $this->nomiText])]);
}
return $dataProvider;
}
}
Finally, in index view:
GridView::widget([
'dataProvider' => $dataProvider,
'filterModel' => $searchModel,
'columns' => [
[
'label' => 'Id Nomi',
'attribute' => 'nomiText',
'value' => function($data) {
return $data->nomi->rus;
},
],

Dynamic default scopes in sequelize.js

I am building kind of multitenancy using sequelize.js. Technically I need to filter all queries by predefined column and dynamic value of the current context. General idea was to use defaultScope to filter out other contexts, something like:
var context = () => { return "some current context id"; }
connection.define('kid', {
firstName: Sequelize.STRING,
photoUrl: Sequelize.STRING,
context: {
type: Sequelize.STRING,
defaultValue: context // this part works, it accepts function
}
}, {
defaultScope: {
where: {
context: context // this does not work, it does not accept function and values is defined only once
}
}
});
However this does not work because defaultScope is defined on the application start.
What is the right way to do this?
The problem is that Sequelize scopes are defined on the model but you need to apply the scope just before the query because that's when you have context such as the user and role.
Here's a slightly modified copy of the scope merge function from Sequelize which you can use in your hooks such as beforeFind()
// Feel free to write a more fp version; mutations stink.
const {assign, assignWith} = require('lodash')
const applyScope = ({scope, options}) => {
if (!scope) {
throw new Error('Invalid scope.')
}
if (!options) {
throw new Error('Invalid options.')
}
assignWith(options, scope, (objectValue, sourceValue, key) => {
if (key === 'where') {
if (Array.isArray(sourceValue)) {
return sourceValue
}
return assign(objectValue || {}, sourceValue)
}
else if (['attributes', 'include'].indexOf(key) >= 0
&& Array.isArray(objectValue)
&& Array.isArray(sourceValue)
) {
return objectValue.concat(sourceValue)
}
return objectValue ? objectValue : sourceValue
})
}
In your model:
{
hooks: {
beforeFind(options) {
// Mutates options...
applyScope({
scope: this.options.scopes.user(options.user)
, options
})
return options
}
}
, scopes: {
user(user) {
// Set the scope based on user/role.
return {
where: {
id: user.id
}
}
}
}
}
Finally in your query, set an option with the context that you need.
const user = {id: 12, role: 'admin'}
YourModel.findOne({
attributes: [
'id'
]
, where: {
status: 'enabled'
}
, user
})
I'm not sure it will help, but you can override a model default scope anytime.
let defaultScope = {
where: {
context: ""
}
};
defaultScope.where.context = context();
model.addScope('defaultScope',defaultScope,{override: true});
Maybe too late here but scopes can take arguments if defined as functions. From documentation Sequelize scope docs if the scope is defined as
scopes: {
accessLevel (value) {
return {
where: {
accessLevel: {
[Op.gte]: value
}
}
}
}
sequelize,
modelName: 'project'
}
you can use it like: Project.scope({ method: ['accessLevel', 19]}).findAll(); where 19 is the dynamic value the scope will use.
As per defaultScope I'm not sure it can be defined as a function

How to change search model for using one field

I have CRUD generated bu Gii. By default, the search in app use one field for each table column. How should i change my search model, for make search in all columns via alone field?
That's my model:
class UserSearch extends User
{
/**
* #inheritdoc
*/
public function rules()
{
return [
[['id', 'status', 'created_at', 'updated_at'], 'integer'],
[['username', 'auth_key', 'password_hash', 'password_reset_token', 'email'], 'safe'],
];
}
/**
* #inheritdoc
*/
public function scenarios()
{
// bypass scenarios() implementation in the parent class
return Model::scenarios();
}
/**
* Creates data provider instance with search query applied
*
* #param array $params
*
* #return ActiveDataProvider
*/
public function search($params)
{
$query = User::find();
$dataProvider = new ActiveDataProvider([
'query' => $query,
]);
$this->load($params);
if (!$this->validate()) {
// uncomment the following line if you do not want to any records when validation fails
// $query->where('0=1');
return $dataProvider;
}
$query->andFilterWhere([
'id' => $this->id,
'status' => $this->status,
'created_at' => $this->created_at,
'updated_at' => $this->updated_at,
]);
$query->andFilterWhere(['like', 'username', $this->username])
->andFilterWhere(['like', 'auth_key', $this->auth_key])
->andFilterWhere(['like', 'password_hash', $this->password_hash])
->andFilterWhere(['like', 'password_reset_token', $this->password_reset_token])
->andFilterWhere(['like', 'email', $this->email]);
return $dataProvider;
}
}
This is how I do it:
public function search($params)
{
..............................
if($this->keyword) {
if(preg_match("/[A-Za-z]+/", $this->keyword) == true) {
$query->andFilterWhere(['like', 'LOWER(CONCAT(name, age, WHATEVERFIELDS)), ', strtolower($this->keyword)]);
} else {
$query->andFilterWhere(['id' => $this->keyword]);
}
}
keyword is not actually a column in the db it is just a variable I attached to the search model. If the keyword is numeric I consider it an ID, you can ignore this part if you want. Otherwise I concat some fields and search in the result. You can also not concat the fields and just add a condition for each field, up to you.
You can see the full file at: https://github.com/Mihai-P/yii2-core/blob/master/models/ContactSearch.php

Resources