In my application, member entities choose a from a pre-defined set of question entities.
I save and iterate over them as a shared list ($member->sharedQuestion).
Now I need to rank them, so I add another column via the link bean (member_question) called 'position'.
My question is - can I make redbean retrieve the questions ORDERed by the column 'position'?
I currently do a
foreach($member->sharedQuestion as $question){.......}
I know I could get the array property and run it through a custom sort handler before I start iterating, but that seems expensive.
Does anyone know of a Redbean method to append some sql (i.e. "ORDER BY position") to a sharedList for example?
Despite having read the Redbean documentation many times, I had missed the (very simple) solution.
Prepending the ->with() method applies extra sql to the query. So what I need to do is;
foreach($member->with("ORDER BY position")->sharedQuestion as $question){.......}
and my problem is elegantly solved!
Related
I was given this project to work on with absolutely no documentation or contact developer. I noticed in the database dump that they are storing what looks like PHP Namespaces for Eloquent models in a couple tables. For example an address table has a string column named "object_type" with the value always being "App\Entities\Client". I searched through the whole project for the PHP code that would use this value. Hopefully to give me insight to it's purpose. Not to my surprise, the project never uses this value. I just see it hard-coding these values upon insert into the DB.
My question is, is this some sort of Database and/or ORM modeling design practice? If so, could you explain how this could be used in a simple practical sense?
Maybe this was some concept the developer had and it never evolved. It's interesting idea but, the idea of joining through MySQL on a string conditional sounds like torture.
Sounds like Laravel polymorphic relationships:
Custom Polymorphic Types.
By default, Laravel will use the fully qualified class name to store the type of the related model.
And, yes, this is a valid modeling technique, though purists rightly argue this technique abuses normal form.
I am not sure what the developers where thinking.
But imagining we are in a forum with thread and replies to each thread. We maybe want to have a Favourites table where we can save replies and threads.
A way to do it would be to have a column in the favourites table called "object_type" (just to use the same term you have in your case) and then when we save an object into the database with eloquent we can use:
$favourite->object_type = get_class($thread); //or get_class($reply) in case we want a reply
$favourite->save();
This way will save the namespace of that class into the database. But laravel will recognise it when we get it from the database.
Hope this cold be helpful.
I'm new to Mongodb (using PHP) and being that I'm used to RDMS I have what maybe a newbie question. I have a collection of "pages" that have a field called "tags" in which I have a series of tags, "happy, sad, angry, irtated".
Now I have another collection, called... let's say "users" and I want the user to be able to specify which tags are important to them... so this collection also has a field called "tags" in which I would have maybe, "Happy, and irtated"
Now... here comes the question, let's say I wanted to correct the spelling of irtated in both collections. Normally the RDMS world, I would have referenced these to a single table and then done an innerjoin such that changing the value in one spot would cascade everywhere... Or let say I wanted to remove a tag from the system... say, I didn't want Happy to be used anymore and I wanted to just remove it from all my collections where it exists...
Thoughts?
Why are you using Mongodb instead of RDBMS? most probably you want higher speed. Since in mongodb most related data in one place (in storage devices) so it is easy to retrieve data.That's why we keep same data in different places (Data redundancy). But when it comes to your case you need to keep more time to do the programming to do the same over RDBMS. So both RDBMS and NOSQL have their won pros and cons, and you will never have both profit from one account(Mongodb).
Symfony ACL allows me to grant access to an entity, and then check it:
if (false === $securityContext->isGranted('EDIT', $comment)) {
throw new AccessDeniedException();
}
However, if I have thousands of entities in the database and the user has access only to 10 of them, I don't want to load all the entities in memory and hydrate them.
How can I do a simple "SELECT * FROM X" while filtering only on the entities the user has access (at SQL level)?
Well there it is: it's not possible.
In the last year I've been working on an alternative ACL system that would allow to filter directly in database queries.
My company recently agreed to open source it, so here it is: http://myclabs.github.io/ACL/
As pointed out by #gregor in the previous discussion,
In your first query, get a list (with a custom query) of all the object_identity_ids (for a specific entity/class X) a user has access to.
Then, when querying a list of objects for entity/class X, add "IN (object_identity_ids)" to your query.
Matthieu, I wasn't satisfied by replying with more of conjectures (since my conjectures don't add anything valuable to the conversation). So I did some bench-marking on this approach (Digital Ocean 5$/mo VPS).
As expected, table size doesn't matter when using the IN array approach. But a big array size indeed makes things get out of control.
So, Join approach vs IN array approach?
JOIN is indeed better when the array size is huge. BUT, this is assuming that we shouldn't consider the table size. Turns out, in practice IN array is faster - except when there's a large table of objects and the acl entries cover almost every object (see the linked question).
I've expanded on my reasoning on a separate question. Please see When using Symfony's ACL, is it better to use a JOIN query or an IN array query?
You could have a look into the Doctrine filters. That way you could extend all queries. I have not done this yet and there are some limitations documented. But maybe it helps you. You'll find a description of the ACL database tables here.
UPDATE
Each filter will return a string and all those strings will be added to the SQL queries like so:
SELECT ... FROM ... WHERE ... AND (<result of filter 1> AND <result of filter 2> ...)
Also the table alias is passed to the filter method. So I think you can add Subqueries here to filter your entities.
Is there a best practice in getting data from multiple database tables using Zend? I would like to know rather than end up wanting to refactor the code I write in the near future. I was reading the Zend documentation and it said that:
"You can not specify columns from a
JOINed tabled to be returned in a
row/rowset. Doing so will trigger a
PHP error. This was done to ensure
the integrity of the Zend_Db_Table is
retained. i.e. A Zend_Db_Table_Row
should only reference columns derived
from its parent table."
I assume I therefore need to use multiple models -- is that correct? If, for example, I want to get out all orders for a particular user id where the date is in between two dates what would I do?
I know that it would be possible to access the two different models from a controller and then combine their respective data in the action but I would not feel happy doing this since I have been reading survivethedeepend.com and it tells me that I shouldn't do this...
Where, why, and how? :)
Thanks!
If you're reading ZFSTDE, in chapter 9 (http://www.survivethedeepend.com/zendframeworkbook/en/1.0/implementing.the.domain.model.entries.and.authors) this problem is addressed by using a data mapper.
Also, you can join 2 tables, just be sure to first call on the select object the setIntegrityCheck(false) method. The docs say that a row should reference a parent table, doesn't mean it can not :)
Stop thinking about Zend_Db_Table as your "model".
You should write your own, rich, domain-centric model classes to sit between your controllers (and views), and your persistence logic (anything that uses Zend_Db/Zend_Db_Table/Zend_Db_Select) to load/store data from the database.
Sure, you can query several db tables at the same time. Take a look at the official ZF docs here http://framework.zend.com/manual/en/zend.db.select.html#zend.db.select.building.join
As for your example with getting all orders of a single user, table relationships are the answer http://framework.zend.com/manual/en/zend.db.table.relationships.html
I have 3 database tables:
article
article_has_tag (2 FK's to the other tables)
tag
I currently show a list of articles with the article's tags shown underneath but the number of queries grows as the list gets longer.
I want to loop over all the articles and get the tag objects from each one in turn.
Can it be done in 1 propel query?
I believe you are using symfony 1.0 and thus Propel 1.2... Whilst the methods already described in the comments talk about alternative methods, there is a direct way to at least solve your problem: add this function to your ArticlePeer class:
public static function getTaggedArticles()
{
$c = new Criteria();
//some filters here, e.g. LIMIT or Criteria::IN array
$ahts = ArticleHasTagPeer::doSelectJoinAll($c);
$articles = array();
foreach($ahts as $aht)
{
if(!isset($articles[$aht->getArticleId()]))
{
$articles[$aht->getArticleId()] = $aht->getArticle();
}
$articles[$aht->getArticleId()]->addTag($aht->getTag());
}
return $articles;
}
where $ahts is short for $article_has_tags. Create a simple array of tags in your Article class (protected array $collTags) along with the addTag() method, if they don't already exist to facilitate this.
This then only executes one SQL query, but consider seriously that without the filter I mention you are potentially hydrating hundreds of objects unnecessarily, and that is a significant performance hit. You may want to research how to hydrate based only on a doSelectRS() call - inspect your BlahPeer classes for how their JOIN methods work, and then this link for how to write custom JOIN methods.
Either way, the method builds a unique array of articles with the ArticleId as the key - if you need a different sort order, you can either sort this array again or use a different array key to organise the collection as you build it.
Unless I'm misunderstanding your question, don't loop over anything as you'll generate bloat of a different kind.
Do a single query where "article" is joined to "article_has_tag" is joined to "tag". The single query should return the specified articles and tag names for the tags they have.
I use Doctrine myself so can't help you with the exact query but Googling brings up stuff like this: http://www.tech-recipes.com/rx/2924/symfony_propel_how_to_left_join/.
Also, the symfony definitive guide (which was written for Propel) should be able to help you.
I assume you are using Propel 1.3 or 1.4, and not yet Propel 1.5 (which is still in beta), as the latter has a very natural support for these multiple joins (inspired, in part, by the Doctrine syntax).
If you defined your foreign keys in the database schema, you should have a static doSelectJoinByAll method in the ArticleHasTagPeer class. If you use this method, the related Article and Tag objects will be hydrated with the same query. You can still pass in a Criteria object that modifies the Article and Tag selection criteria. I know this is a bit strange, since you probably want to start from the Article objects, and this was one of the driving factors for the change in Propel 1.5. In Symfony you can also use the DbFinderPlugin, this will already give you this capability in Propel 1.3 (it needs a small patch for Propel 1.4). In fact, Propel 1.5 is mostly written by François Zaniotto, the author of the DbFinderPlugin.
Short answer is no.
But with some efforts you still can do that. Here's list of options:
Use dbFinderPlugin plugin
Write your own peer method (say, doSelectPostWithUsersAndComments).
Migrate to Propel 1.5
Migrate to Doctrine