How to use Yii2 multilingual behavior - yii

I’m having a problem using Yii2 multilingual behavior and I hope someone here can help me.
This is the my database
CREATE TABLE IF NOT EXISTS `post` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`created_at` datetime NOT NULL,
`updated_at` datetime NOT NULL,
`enabled` tinyint(1) NOT NULL DEFAULT '1',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE IF NOT EXISTS `postLang` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`post_id` int(11) NOT NULL,
`language` varchar(6) NOT NULL,
`title` varchar(255) NOT NULL,
`content` TEXT NOT NULL,
PRIMARY KEY (`id`),
KEY `post_id` (`post_id`),
KEY `language` (`language`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
ALTER TABLE `postLang`
ADD CONSTRAINT `postlang_ibfk_1` FOREIGN KEY (`post_id`) REFERENCES `post` (`id`) ON DELETE CASCADE ON UPDATE CASCADE;
And this PostlangController
use omgdef\multilingual\MultilingualBehavior;
public function behaviors()
{
return [
'ml' => [
'class' => MultilingualBehavior::className(),
'languages' => [
'vi-VN' => 'Russian',
'en-US' => 'English',
],
//'languageField' => 'language',
//'localizedPrefix' => '',
//'requireTranslations' => false',
//'dynamicLangClass' => true',
'langClassName' => PostLang::className(), // or namespace/for/a/class/PostLang
'defaultLanguage' => 'vi-VN',
'langForeignKey' => 'post_id',
'tableName' => "{{%postLang}}",
'attributes' => [
'title', 'content',
]
],
'verbs' => [
'class' => VerbFilter::className(),
'actions' => [
'delete' => ['post'],
],
],
];
}
and output orror
Call to undefined method backend\controllers\PostlangController::primaryKey()

don't add the behavior to the controller add it to your model
Attaching this behavior to the model (Post in the example).
https://github.com/OmgDef/yii2-multilingual-behavior

Related

SQL Server : how to set a column to a random value?

I'm using SQL Server, I'm not experienced in T-SQL, but I want to generate random value including letters and numbers for one column for my project:
CREATE TABLE [dbo].[Orders]
(
[Id] INT NOT NULL,
[UserId] INT NOT NULL,
[MedicineId] INT NOT NULL,
[CourierId] INT NULL,
[ReadyForDelivery] BIT NOT NULL,
[OrderNumber] NVARCHAR(11) NOT NULL,
CONSTRAINT [PK_Orders] PRIMARY KEY CLUSTERED ([Id] ASC)
);
Id is my primary key also I want to put a random number and letters in the OrderNumber column. How can I do that?
I use migration when I'm creating this table
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable(
name: "Orders",
columns: table => new
{
Id = table.Column<int>(type: "int", nullable: false)
.Annotation("SqlServer:Identity", "1, 1"),
UserId = table.Column<int>(type: "int", nullable: false),
MedicineId = table.Column<int>(type: "int", nullable: false),
CourierId = table.Column<int>(type: "int", nullable: false),
ReadyForDelivery = table.Column<bool>(type: "bit", nullable: false),
OrderNumber = table.Column<string>(type: "nvarchar(max)", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_Orders", x => x.Id);
});
}

foreign key camel case issue in postgres on heroku server

i am creating table on heroku successfully but the problems is foreign key when add foreign key it will automatically created in small letter by default
postgres accept foreign key like serviceId format
this is my table
CREATE TABLE service_categories (
id serial PRIMARY KEY,
"serviceId" integer NOT NULL,
service_category_name VARCHAR ( 50 ) NOT NULL,
"createdAt" TIMESTAMP DEFAULT NOW(),
"updatedAt" TIMESTAMP DEFAULT NOW()
);
but on heroku its created serviceid rather then serviceId
any body can help how can i create foreign key like serviceId
just double quotes in the model like
const Order = db.define("my_orders", {
id: {
type: Sequelize.INTEGER,
autoIncrement: true,
allowNull: false,
primaryKey: true,
},
"serviceSubCategoryId": {
type: Sequelize.INTEGER
},
"userId": {
type: Sequelize.INTEGER
}
});

Category and Sub-Categories with NodeJS and SQL Result

I am trying to build a JSON with NodeJS and SQL result.
The database is:
CREATE TABLE category (
id int(10) unsigned NOT NULL AUTO_INCREMENT,
title varchar(255) NOT NULL,
parent_id int(10) unsigned DEFAULT NULL,
PRIMARY KEY (id),
FOREIGN KEY (parent_id) REFERENCES category (id)
ON DELETE CASCADE ON UPDATE CASCADE
);
CREATE TABLE `items` (
`id` int unsigned NOT NULL AUTO_INCREMENT,
`cat_id` int unsigned DEFAULT NULL,
`parent_id` int unsigned DEFAULT NULL,
`name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
PRIMARY KEY (`id`),
KEY `cat_id` (`cat_id`),
KEY `sub_id` (`parent_id`),
CONSTRAINT `cat_id` FOREIGN KEY (`cat_id`) REFERENCES `category` (`id`) ON DELETE CASCADE ON UPDATE CASCADE,
CONSTRAINT `sub_id` FOREIGN KEY (`parent_id`) REFERENCES `category` (`parent_id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;
BEGIN;
INSERT INTO `category` VALUES (1, 'Colazione', NULL);
INSERT INTO `category` VALUES (2, 'Pranzo', NULL);
INSERT INTO `category` VALUES (3, 'Primi piatti', 2);
INSERT INTO `category` VALUES (4, 'Second dish', 2);
INSERT INTO `category` VALUES (5, 'Other things for lunch', 2);
COMMIT;
-- ----------------------------
-- Records of items
-- ----------------------------
BEGIN;
INSERT INTO `items` VALUES (1, 1, NULL, 'Cornetto');
INSERT INTO `items` VALUES (2, 3, 2, 'Pasta al sugo 1');
INSERT INTO `items` VALUES (3, 3, 2, 'Pasta al sugo 2');
INSERT INTO `items` VALUES (4, 3, 2, 'Pasta al sugo 3');
INSERT INTO `items` VALUES (5, 3, 2, 'Pasta al sugo 1 X');
INSERT INTO `items` VALUES (6, 3, 2, 'Pasta al sugo 2 X');
INSERT INTO `items` VALUES (7, 4, 2, 'Pasta al sugo 3 X');
COMMIT;
SET FOREIGN_KEY_CHECKS = 1;
The expected JSON is:
Category:
Sub-Categories:
Items:
If category doesn't got any sub-categories it will print:
Category:
Items:
We got more than one categories and each categories can have more than one sub-categories.
Each sub-categories can have more than one item.
How can I build a JSON result with NodeJS with SQL Query?
Expected JSON:
{
"menu": {
"categories": [
{
"id_category": 1,
"category_title": "Colazione",
"items": [
{
"id_item": 1,
"title": "Cornetto"
}
]
},
{
"id_category": 2,
"category_title": "Pranzo",
"subcategories": [
{
"title_subcategories": "Primi piatti",
"items": [
{
"id_item": 1,
"title": "Pasta al sugo 1"
},
{
"id_item": 2,
"title": "Pasta al sugo 2"
}
]
},
{
"title_subcategories": "Secondi piatti",
"items": [
{
"id_item": 1,
"title": "Pasta al sugo 3"
}
]
}
]
}
]
}
}
Here's what I came up with, although I haven't tested it:
async function buildJson(categories, items) {
// `query` is some function that queries the DB
const categries = await query('SELECT id AS id_category, title AS category_title, parent_id FROM categories');
const items = await query('SELECT id AS id_item, title AS item_title, cat_id FROM items');
const data = {
menu: {
categories: [],
},
};
const subcategories = categories.filter(category => category.parent_id !== null);
categories.filter(category => category.id_parent === null)
.forEach(category => {
data.menu.categories.push({
id_category: category.id_category,
category_title: category.category_title,
});
data.menu.categories.forEach(_category => {
_category.items = items.filter(item => item.cat_id === _category.id_category)
.map(item => ({
id_item: item.id_item,
title: item.title,
}));
_category.subcategories = categories.filter(__category => __category.parent_id === _category.id);
_category.subcategories.forEach(subcategory => {
subcategory.items = items.filter(item => item.cat_id === subcategory.id_category)
.map(item => ({
id_item: item.id_item,
title: item.title,
}));
});
});
});
return data;
}

1054 error, unknown column in where clause

I keep getting this error when the column does exist, can anyone tell me why?
This is my query:
update testtable2 set testtable2.BE = testtable1.`1962`
where testtable2.`year`= 1962
and testtable2.PERMNO = testtable1.testcolumn
And I get this response:
Error Code: 1054. Unknown column 'testtable1.testcolumn' in 'where clause'
testtable1 structure:
`testcolumn` varchar(255) DEFAULT NULL,
`FIRSTYEAR` varchar(255) DEFAULT NULL,
`LASTYEAR` varchar(255) DEFAULT NULL,
`1926` varchar(255) DEFAULT NULL,
`1927` varchar(255) DEFAULT NULL,
`1928` varchar(255) DEFAULT NULL,
`1929` varchar(255) DEFAULT NULL,
`1930` varchar(255) DEFAULT NULL,
`1931` varchar(255) DEFAULT NULL,
`1932` varchar(255) DEFAULT NULL,
`1933` varchar(255) DEFAULT NULL,
`1934` varchar(255) DEFAULT NULL,
`1935` varchar(255) DEFAULT NULL,
`1936` varchar(255) DEFAULT NULL,
`1937` varchar(255) DEFAULT NULL,
`1938` varchar(255) DEFAULT NULL,
`1939` varchar(255) DEFAULT NULL,
`1940` varchar(255) DEFAULT NULL,
`1941` varchar(255) DEFAULT NULL,
`1942` varchar(255) DEFAULT NULL,
`1943` varchar(255) DEFAULT NULL,
`1944` varchar(255) DEFAULT NULL,
`1945` varchar(255) DEFAULT NULL,
`1946` varchar(255) DEFAULT NULL,
`1947` varchar(255) DEFAULT NULL,
`1948` varchar(255) DEFAULT NULL,
`1949` varchar(255) DEFAULT NULL,
`1950` varchar(255) DEFAULT NULL,
`1951` varchar(255) DEFAULT NULL,
`1952` varchar(255) DEFAULT NULL,
`1953` varchar(255) DEFAULT NULL,
`1954` varchar(255) DEFAULT NULL,
`1955` varchar(255) DEFAULT NULL,
`1956` varchar(255) DEFAULT NULL,
`1957` varchar(255) DEFAULT NULL,
`1958` varchar(255) DEFAULT NULL,
`1959` varchar(255) DEFAULT NULL,
`1960` varchar(255) DEFAULT NULL,
`1961` varchar(255) DEFAULT NULL,
`1962` varchar(255) DEFAULT NULL,
`1963` varchar(255) DEFAULT NULL,
`1964` varchar(255) DEFAULT NULL,
`1965` varchar(255) DEFAULT NULL,
`1966` varchar(255) DEFAULT NULL,
`1967` varchar(255) DEFAULT NULL,
`1968` varchar(255) DEFAULT NULL,
`1969` varchar(255) DEFAULT NULL,
`1970` varchar(255) DEFAULT NULL,
`1971` varchar(255) DEFAULT NULL,
`1972` varchar(255) DEFAULT NULL,
`1973` varchar(255) DEFAULT NULL,
`1974` varchar(255) DEFAULT NULL,
`1975` varchar(255) DEFAULT NULL,
`1976` varchar(255) DEFAULT NULL,
`1977` varchar(255) DEFAULT NULL,
`1978` varchar(255) DEFAULT NULL,
`1979` varchar(255) DEFAULT NULL,
`1980` varchar(255) DEFAULT NULL,
`1981` varchar(255) DEFAULT NULL,
`1982` varchar(255) DEFAULT NULL,
`1983` varchar(255) DEFAULT NULL,
`1984` varchar(255) DEFAULT NULL,
`1985` varchar(255) DEFAULT NULL,
`1986` varchar(255) DEFAULT NULL,
`1987` varchar(255) DEFAULT NULL,
`1988` varchar(255) DEFAULT NULL,
`1989` varchar(255) DEFAULT NULL,
`1990` varchar(255) DEFAULT NULL,
`1991` varchar(255) DEFAULT NULL,
`1992` varchar(255) DEFAULT NULL,
`1993` varchar(255) DEFAULT NULL,
`1994` varchar(255) DEFAULT NULL,
`1995` varchar(255) DEFAULT NULL,
`1996` varchar(255) DEFAULT NULL,
`1997` varchar(255) DEFAULT NULL,
`1998` varchar(255) DEFAULT NULL,
`1999` varchar(255) DEFAULT NULL,
`2000` varchar(255) DEFAULT NULL,
`2001` varchar(255) DEFAULT NULL,
) ENGINE=InnoDB DEFAULT CHARSET=utf8
testtable2 structure:
`PERMNO` varchar(255) DEFAULT NULL,
`year` varchar(255) DEFAULT NULL,
`BE` varchar(255) DEFAULT NULL
You forgot to join them I think...
update testtable2 tt2
inner join testtable1 tt1 on
tt1.testcolumn = tt2.PERMNO AND tt2.`year`= 1962
set tt2.BE = tt1.`1962`
Or a simpler approach:
update testtable2, testtable1
set testtable2.BE = testtable1.`1962
where testtable2.`year`= 1962
and testtable2.PERMNO = testtable1.testcolumn

Laravel Eloquent ORM for Social Network

I have the following database setup for my status posts. For each post, users can like the post, comment on the post or can even be tagged in the original post by the author.
I'm trying to setup my Resourceful controller 'Post' to bring back all the data via JSON object but I can't properly find the comment, likes or tags usernames. I'm using Sentry 2 for auth if that makes a difference.
Here's the database setup:
CREATE TABLE Users (
id INT NOT NULL AUTO_INCREMENT,
first_name VARCHAR(30),
last_name VARCHAR(30),
many more...
);
CREATE TABLE Posts (
postID INT NOT NULL AUTO_INCREMENT,
caption VARCHAR(200),
description VARCHAR(200),
fromID INT(10) UNSIGNED NOT NULL,
toID INT(10) UNSIGNED NOT NULL,
icon VARCHAR(200),
link VARCHAR(200),
message TEXT,
storyType INT,
type ENUM ('LINK', 'PHOTO', 'STATUSUPDATE', 'VIDEO' ),
createdTime DATE,
PRIMARY KEY (postID),
FOREIGN KEY (fromID) REFERENCES users (id),
FOREIGN KEY (toID) REFERENCES users (id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
CREATE TABLE Likes (
likeID INT NOT NULL AUTO_INCREMENT,
fromID INT(10) UNSIGNED NOT NULL,
postID INT NOT NULL,
createdDate DATE,
PRIMARY KEY (likeID),
FOREIGN KEY (fromID) REFERENCES users (id),
FOREIGN KEY (postID) REFERENCES Posts (postID)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
CREATE TABLE Comments (
commentID INT NOT NULL AUTO_INCREMENT,
fromID INT(10) UNSIGNED NOT NULL,
postID INT NOT NULL,
comment TEXT,
createdDate DATE,
PRIMARY KEY (commentID),
FOREIGN KEY (fromID) REFERENCES users (id),
FOREIGN KEY (postID) REFERENCES Posts (postID)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
CREATE TABLE Tags (
tagID INT NOT NULL AUTO_INCREMENT,
userID INT(10) UNSIGNED NOT NULL,
postID INT NOT NULL,
PRIMARY KEY (tagID),
FOREIGN KEY (userID) REFERENCES users (id),
FOREIGN KEY (postID) REFERENCES Posts (postID)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
My Post Controller, I just have a simple page that spits out everything. I don't want to loop through anything in my view file, I just want to bring back the json full object.
class PostController extends BaseController {
public function show($id)
{
$post = Post::with(array('comments', 'from', 'tags', 'likes'))->find($id);
return View::make('samplepage')->with('data', $post);
}
}
My Post Model:
class Post extends Eloquent {
protected $table = 'Posts';
protected $primaryKey = 'postID';
public function comments()
{
return $this->hasMany('Comment','postID');
}
public function tags()
{
return $this->hasMany('Tag','postID');
}
public function likes()
{
return $this->hasMany('Like','postID');
}
public function from()
{
return $this->belongsTo('User', 'fromID')->select(array('id', 'first_name', 'last_name'));
}
public function users()
{
return $this->belongsTo('User', 'fromID');
}
}
Comment Model:
class Comment extends Eloquent {
protected $table = 'Comments';
protected $primaryKey = 'commentID';
public function post() {
return $this->belongsTo('Post','fromID');
}
public function user() {
return $this->belongsTo('User', 'fromID')->select(array('id', 'first_name', 'last_name'));
}
}
Tag Model:
class Tag extends Eloquent {
protected $table = 'Tags';
protected $primaryKey = 'tagID';
}
I even setup the following in my user model but it makes no difference.
User Model:
public function posts() {
return $this->hasMany('Post','id');
}
public function comments() {
return $this->hasMany('Comment','id');
}
Everything works great with this setup and when I hit posts/2 with this the following code, I get the below object back.
$post = Post::with(array('comments', 'from', 'tags', 'likes'))->find($id);
return View::make('samplepage')->with('data', $post);
{
postID: "2",
toID: "8",
comments: [
{
commentID: "2",
comment: "second comment",
fromID: "1",
postID: "2",
createdDate: "2014-02-15"
}
],
from: {
id: "4",
first_name: Paul,
last_name: Davis
},
tags: [
{
tagID: "1",
userID: "2",
postID: "2"
},
{
tagID: "2",
userID: "3",
postID: "2"
}
],
likes: [
{
likeID: "1",
fromID: "2",
postID: "2",
createdDate: "2013-01-04"
},
{
likeID: "2",
fromID: "3",
postID: "2",
createdDate: "2013-02-05"
}
]
}
But what I want is the following, where for each tag, like and comment to concatenate the first and last name and get them back with the object.
{
postID: "2",
toID: "4",
comments: [
{
commentID: "2",
comment: "second comment",
fromID: "1",
from: {
"name": "Jason Terry",
"id": "721286625"
},
postID: "2",
createdDate: "2014-02-15"
}
],
from: {
id: "4",
first_name: Paul,
last_name: Davis
},
tags: [
{
tagID: "1",
userID: "2",
from: {
"name": "David Lee",
"id": "721286625"
},
postID: "2"
},
{
tagID: "2",
userID: "3",
from: {
"name": "Paul Pierce",
"id": "721286625"
},
postID: "2"
}
],
likes: [
{
likeID: "1",
fromID: "2",
from: {
"name": "David Lee",
"id": "721286625"
},
postID: "2",
createdDate: "2013-01-04"
},
{
likeID: "2",
fromID: "3",
from: {
"name": "Al Davis",
"id": "721286625"
},
postID: "2",
createdDate: "2013-02-05"
}
]
}
I have searched Stackoverflow, countless Laravel blogs, the official documentation for 2 weeks now and I can't seem to solve this. Any help is wonderfully appreciate.
Update:
With Tony's answer below I added
$post = Post::with(array('comments.users', 'from', 'tags.users', 'likes.users'))->find($id);
Then I added
public function users()
{ return $this->belongsTo('User', 'fromID')->select(array('id', 'first_name', 'last_name'));
}
to the comments, tags, and likes model. And the object works great now.
But my debugger shows the following
select `id`, `first_name`, `last_name` from `users` where `users`.`id` in ('1')
select `id`, `first_name`, `last_name` from `users` where `users`.`id` in ('4')
select `id`, `first_name`, `last_name` from `users` where `users`.`id` in ('2', '3')
select `id`, `first_name`, `last_name` from `users` where `users`.`id` in ('2', '3')
In short, it runs 4 queries on my users table. Isn't this redundant? Shouldn't it be doing 1 query to the users table instead of 1 query for the original post user, 1 query for the comments users, 1 query for the tags users, and 1 query for the likes users?
It looks like you want to use nested relationships.
$post = Post::with('comments.from', 'from', 'tags.from', 'likes.from')->find($id);
You would also need the "from" relationship coded into each of those models.
To get your concatenated name; you'd need the following in your User model
protected $appends = array('name');
protected $hidden = array('first_name', 'last_name'); //this is optional
public function getNameAttribute()
{
return $this->attributes['first_name'] . ' ' . $this->attributes['last_name'];
}
it is little old post but you can also do this,
public function from()
{
return $this->belongsTo('User', 'fromID')
->select(array('id',DB::raw("CONCAT(firstname,' ', lastname) as name")));
}