Kohana 3.1 ORM: How to implement a "unique" validation rule? - php

does exists a "unique" validation rule (if does, how to implement it?) or must be implemented via callback?
Thanks.

)
As far as I know there is no universal "unique" (or "is_unique") rule of Validation class.
That's probably because of not regular nature of this kind of check.
However, if you would like do it nicely, you could create a 'base model' for all your models you use in your application (make them extend the base one).
Then, the uniqueness could be checked more or less like this:
public function is_unique($id)
{
return ! (bool) DB::select(array(DB::expr('COUNT(id)'), 'total'))
->from($this->_table_name)
->where('id', '=', $id)
->execute()
->get('total');
}
In your validation rules you have to add this rule:
array('id' => array(array(array($this, 'is_unique')));
I have internal model rules stored in the method rules(), as recommended.
So this could be a live example:
class Model_Base_Model extends ORM
{
public function rules()
{
return array(
'id' => array(
array(array($this, 'is_unique')),
);
}
public function is_unique($id)
{
return ! (bool) DB::select(array(DB::expr('COUNT(id)'), 'total'))
->from($this->_table_name)
->where('id', '=', $id)
->execute()
->get('total');
}
}
Now every model extending the Model_Base_Model will be now able to check it's uniqueness while creating.
Hope this helps! :)

In Kohana 3.2 ORM has a unique() method that does the check, I'm not sure if it exists in 3.1, but it should.
With that you can just add a rule to your model like this:
array(array($this, 'unique'), array('some_field', ':value')),
and it will check if some_field is unique

Read this: http://kohanaframework.org/3.1/guide/kohana/security/validation

Related

Laravel conditional relationship - hasOne specified by model's type

I have a model Chapter which have field type than can be (article, video, quiz). To solve my problem I have to create a new model Quiz which will have relationship oneToOne with Chapter model whether type of Chapter == "quiz".
I've tried something like this and it works when type == "quiz" only. I guess I'll have to return other relations for other types for it to work, but I don't have nothing to return so I wanted to leave it empty for other types.
public function quizQuestions(){
if($this->chapter_type == "QUIZ"){
return $this->hasMany(QuizQuestion::class);
}
}
The point is, I want to somehow return empty relation for other types. I'm building an app in Laravel Nova and I wanted to hide Quiz table if a chapter is not type of "quiz" but it can't be done this way.
NovaDependencyContainer::make([
HasMany::make('QuizQuestions'),
])->dependsOn('chapter_type' , \App\Models\Chapter::QUIZ),
I might have missed something in documentation or I just don't understand something so thanks in advance for you help and advices!
Try returning null otherwise:
public function quizQuestions(){
if($this->chapter_type == "QUIZ"){
return $this->hasMany(QuizQuestion::class);
}
return $this->hasMany(QuizQuestion::class)->where('id', -1);
}
I advise you to re-think your Model, but not too many edits.
I have done things like you want in this manner:
return $this->hasMany('App\Models\Main\QuizQuestion','id','id')->where('chapter_type', '=', 1);
then ->where('chapter_type', '=', 2);
Works like a charm!!
After couple of sleepless nights and days full of crying I finally came up with a solution:
public function fieldsForDetail(Request $request)
{
if ($this->model()->chapter_type == "QUIZ") {
return [
$this->chapterCredentials(),
HasMany::make('QuizQuestions'),
];
}
return [
$this->chapterCredentials(),
];
}
public function chapterCredentials()
{
return $this->merge([
Text::make('Chapter Name', 'chapter_name')
->sortable()
->rules('required', 'max:100'),
TextArea::make('Chapter Description', 'chapter_description'),
Select::make('Chapter Type', 'chapter_type')->options([
\App\Models\Chapter::ARTICLE => 'Article',
\App\Models\Chapter::VIDEO => 'Video',
\App\Models\Chapter::QUIZ => 'Quiz',
])->rules('required'),
BelongsTo::make('Course', 'Course')->searchable(),
]);
}
Now in a display view it shows linked model QuizQuestion only when type of the model equals "QUIZ"

Laravel & Ardent - orderBy in $relationsData

In Eloquent, you can do this:
public function children() {
return $this->hasMany('page');
}
And in Ardent, you can do this:
public static $relationsData = [
'children' => [self::HAS_MANY, 'Page'],
];
In Eloquent, you can also do this:
public function children() {
return $this->hasMany('page')->orderBy('sort_order', 'desc');
}
Is there any way to do that, or get the same effect as that in Ardent?
I really like the short Ardent notation, but don't want to have to call $page->children->ordered() with a scope just to order them, as they'll need to be ordered every single time it's called anyway.
As it turns out, it's just not possible. You need the full definition if you want to do anything more than the basic relation functionality.

Maintaining an MVC pattern, making database calls from model using PHPs Laravel 4

I'm trying to maintain an MVC pattern using the Laravel 4 framework, in my last project I made all the database queries from the controller, I have now learned that is a terrible practice and I'm trying to figure out how to do the same from the model. Here is what I would normally do.
Controller
public function serve($company)
{
$review = Review::select('head', 'body', 'logo', 'name')->where('company', '=', $company)->firstOrFail();
return View::make('layouts.singlereview', compact('review'));
}
Model
class Review extends Eloquent {
protected $table = 'reviews';
protected $guarded = [
'id', 'company', 'head', 'body'
];
}
When I move the $review variable and database query into the model then I get the error on the view with undefined variable. How do I pass the $review variable from the model to the controller?
Thanks!
Actually you will still need to do some stuff with your Models in your controller. Use Repository Pattern do to so, which is pretty similar of querying your models in your controller, but being less verbose:
public function serve($company)
{
return View::make('layouts.singlereview')->withReview(with(new Review)->getCompanyData($company));
}
And put the whole logic in your repository:
class Review extends Eloquent {
public function getCompanyData($company)
{
return static::select('head', 'body', 'logo', 'name')
->where('company', '=', $company)
->firstOrFail();
}
}
Also, while you are on the subject of creating good code, you might as well check out Eloquent relationships. They may require database restructuring for certain occurrences, but most of the time you should be good.
With the code you have provided, I can assume that review and company are in a one-to-one relationship, so once this is defined, you can simply retrieve a company object, then do,
$review = $company->review;

Yii: BELONGS_TO relation returns null if I change its name

I would like to know why the framework might have this strange behavior.
If I define the relation in my Event model as weird or any other name besides interest, it works properly getting an object of the class Interest.
public function relations()
{
return array_merge(
parent::relations(),
array(
'weird' => array(self::BELONGS_TO, 'Interest', 'interest_id'),
));
}
But if I change the name to interest it returns null
public function relations()
{
return array(
'interest' => array(self::BELONGS_TO, 'Interest', 'interest_id'),
);
}
So simply changing the name to interest means the relation will return null
Do you have any variables on the Event called interest you can't override native class variables with Yii specials like relations and magic methods. If not then something stranger is going on here.

how to change a model safe attributes in yii

I have a CActiveRecord model, and I need to change safe attributes list in that model.
I have defined the safeAttributes method inside my model, like the following :
public function safeAttributes()
{
return array(
'name, bio',
);
}
the problem is 'bio' is not being considered in my safe attribute assign. I tried to dump the model safeAttributeNames attribute in my model, and what I've got was completely different from what safeAttributes should return.
Am I doing this in the right way ?
cheers,
Firas
Assuming that you are using Yii 1.0.x then that is the correct way to do it.
If you are using Yii 1.1.x then it's changed. Have another read of the documentation.
public function rules()
{
return array(
array('username, password', 'required'),
array('rememberMe', 'boolean'),
array('password', 'authenticate'),
array('something', 'safe'),
array('someOtherThing', 'unsafe'),
);
}

Categories