Database/Models & Latte plus ErrorPresenter

2 months ago

farhanianz
Member | 8
+
0
-

I've got myself stuck in a number of situations. I read the documentation & had a look in this forum.
Either documentation is so brief or not available & in case of forum it seemed recent posts in English is not in a great amount. As a beginner with the nette framework (3.*), there's a chance that I might have mistakenly claimed something. Perdon this. But my points are:

A. Controls & Latte

As per the Documentation we can pass variable to the controls which is fine & seemed impressive at first. Then the context-aware latte escaping could not be smart enough to get me through. Take a look at this example:

	File: SomeFormFactory.php
	.
	.
	.
	.

	public function __construct(FormFactory $factory, MyModel $model)
	{
		$this->factory = $factory;
		$this->dataProviderModel = $data;
		// Even I've tried to inject request $request, presenter $presenter to be able to set flash & get params
	}

	public funciton create(callable $onSuccess, array $array): Form
	{
		// say, we need an array $array to be passed for a reason
		// other codes...

		// We may need request $request param

		// We may need to set flash message & redirect (idk, it's a proper way)

		// We may need to access models/services here.
	}
	?>

So, registered it in the services section of neon. Injected whatever we need on the form in the. It returns me a bunch of errors.

1. {control someForm $array} the array gets converted to string, I found zero way to solve that.
even I tried to achieve this by creating createComponentSomeForm(array $array), it is'nt an array anymore after passing it from latte. |noescape is not allowed in control macro.
2. So I thought I can get that $array to from model, the model need context $database. I can't recall the exact error (maybe I'll post later here) but it fails (maybe due to other dependacy of the model) (I'll clarify later hopefully).
3. No I can't have flashes here, tried in different way. Am I right? But what if I need it?

B: Let's talk about other thing. Imagine we need nested categories (well at least 3 level deep). I think to achieve this I need a database design like this (making it simple):

id 			- int, not null, auto-increment, primary
parent_id 	- int, null, default: null
title		- varchar, not null

The reason I'm not choosing another table is because I'll need 3 tables to get 3 levels deep nesting & it will be much complex. What if I need more nesting levels?

So, Nette database core/explorer can get it using “where parent_id = $parentId” but what I would I do in latte?

I've got a model:
getCats() → returns cats ActiveRow (where parent_id = null)
getSubCats($childId) → checks if it has parent & returns sub cats (where id = $child->parent_id)

	so in latte:
	{foreach $cats as $cat}
		{$cat->title}
		{* how do I access model/database *}
		way1: {php $sub = $this->model->getSubCats($cat->id) : not working - can't found the model
		way2: {$cat->related(cats.parent_d)} silly I know, but not works
	.
	.
	.

I don't know how to achieve this. I need it in various situation. Should I try keeping model->getSubCats($childId) directly in the presenter? Can I use then $this->getSubCats($child->parent_id) from latte? What about DRY/separation of concern then?

C: Error & Error4×x presenters seemed a little more confusing. Can't it be simplified? Perhaps a easy way to set it up? Can the error & error4×x be merged together? How do I set it up if I map the app for multi module structure?

Anyway, It's a long message, I might have missed to provide all necessary information. Hopefully I'll. How do I overcome these situations?

Last edited by farhanianz (2020-06-02 10:35)

2 months ago

stepos2
Backer | 7
+
0
-

ad B: This should actually work, provided you have correctly set up foreign keys:

$cat->related('cats.parent_id')

2 months ago

farhanianz
Member | 8
+
0
-

stepos2 wrote:

ad B: This should actually work, provided you have correctly set up foreign keys:

$cat->related('cats.parent_id')

No, It actually won't work. Can I really set up foreign keys in same Table?

This is the table structure. All cats & subcats are here. I already described the issue if I use another table(s) for storing subcats.

	id 			- int, not null, auto-increment, primary
	parent_id 	- int, null, default: null
	title		- varchar, not null

If I use PHP with Database, it works fine. Take a look at the code:

	// @var  $database Nette\Database\Context
	$cats = $this->database->table('cats')->where->('parent_id', null);
	foreach ($cats as $id => $cat) {
		echo "main: $cat->title :";
		if ($cat->parent_id !== null) {
			$childId = $cat->id;
			$subs = $this->database->table('cats')->where('parent_id', $childId);
			// Just making sure if the category is still available (not deleted)
			if ($subs) {
				echo "sub: $subs->title ,";
			}
		}
		echo "<hr>";
	}

Well, can I do this on latte? Or can I access model/presenter methods from latte template? How?

I think I should have a way for accessing the models/presenters method (or even better allowed/assigned methods) from template. Currently the workarounds I can think of are

  1. Create a global function that will return the ActiveRow $subcats
  2. Maybe adding a filter could help

Well, I'vent tested those above two workarounds yet. I'm really searching for a quite good solution. Because I already started the project & a lot of it's logic/codes using nette/sandbox.

Thanks for replying.

Last edited by farhanianz (2020-06-02 13:01)

2 months ago

stepos2
Backer | 7
+
+1
-

farhanianz wrote:

No, It actually won't work. Can I really set up foreign keys in same Table?

Why doesn't it work, what error does it throw? Yes, foreign key referencing the same table is valid.

2 months ago

farhanianz
Member | 8
+
+1
-

stepos2 wrote:

farhanianz wrote:

No, It actually won't work. Can I really set up foreign keys in same Table?

Why doesn't it work, what error does it throw? Yes, foreign key referencing the same table is valid.

My bad! I was confused about that & thought it is not valid to assign foreign key referencing the same table. I just set up the foreign key & related() is working. I needed to loop through the results returned by related().

Thanks.

2 months ago

farhanianz
Member | 8
+
0
-

In the mean time, I was looking through the Nette/Application/Bridges/ApllicationLatte.

I found that there are a number of useful $variables defined. For eg: $user, $presenter, $baseurl, $httpRequest etc.
Which would be enough to call model/presenters method from the template. It's helpful. But never written clearly about that.

I think those framework specific documentations should also be written in the official documentation. As far as I can remember, only the framework specific macros are documented there. `I suggest to add those in the documentation, if it's really not documented yet`. Thanks to the Nette team, contributters & community.

I can say the point B that I wrote is solved.
I'm looking for replies for the other two Points (A & C).

Last edited by farhanianz (2020-06-02 14:01)