Love Fuel?    Donate

FuelPHP Forums

Ask your question about FuelPHP in the appropriate forum, or help others by answering their questions.
Relation one to many array indexes
  • Hi, what's the best way to have a relation (one to many) array to be indexed with a column value, instead of primary key value? For example, I have Model_Article with many Model_ArticleTranslation and when I fetch them, they are indexed by id (primary key), but I would need them to be indexed by another column (in example, by the language id). Thanks for your attention and support.
  • Only by rewriting the array yourself. The key value has to be unique and the only way to ensure that is to index by primary key. Anything else would also add unneeded overhead.
  • Franceso. Can you show me in your models, how did you created the relations.
    Your ORM Relations to get the content of an Article from the ArticleTranslation table? Thanks.
  • Model_Article:
    protected static $_has_many = array(
    'translations' => array(
    'key_from' => 'id',
    'model_to' => 'Model_ArticleTranslation',
    'key_to' => 'article_id',
    'cascade_save' => true,
    'cascade_delete' => true,
    )
    ); Model_ArticleTranslation:
    protected static $_belongs_to = array(
    'article' => array(
    'key_from' => 'article_id',
    'model_to' => 'Model_Article',
    'key_to' => 'id',
    'cascade_save' => false,
    'cascade_delete' => false,
    )
    ); I never retrieve a Model_Article from a Model_ArticleTranslation.
    I extract one or more Model_Article joining the translations table, here an example of retrieving all articles (with paging): $articles = Model_Article::query()
    ->related('translations')
    ->and_where_open()
    ->or_where('translations.language_id', Model_Language::get_current_language()->id)
    ->or_where('translations.language_id', Model_Language::get_default_language()->id)
    ->and_where_close()
    ->order_by($filter, $filter)
    ->limit(Pagination::$per_page)
    ->offset(Pagination::$offset)
    ->get(); The result is an array of articles with two (or one) translations inside each 'translations' relation. Every translation insided 'translations' array is indexed by its id. For the purpose of my first post, it could be convenient to add an 'index_column' in the $has_many array (default primary key) and index the array by 'index_column' passing the index_column value in hydrate method (\Orm\Query).
  • Thanks. That's what I did myself.
    But i wanted to use ORM in order to simplify, and to be honest I find that building that query is not satisfying as i hoped. EDIT: Francesco, can you do a cascade save with that setup? If so how? i tried this.
    $product= Model_Produto::find(2, array( 'related' => array( 'translations' => array( 'where' => array( array('id_lang', '=', 1), ), ), ), )); [/CODE] I get a join from Products and my Products_Translation tables. table Products only has 3 ids, no field 'name' and I can do this: $product->brand_id = 1337; $product->save(); But I can't do $product->name = "12121"; So how can i have a cascade save, and access and edit fields of the related tables? Is it possible at all?[CODE]
    $product= Model_Produto::find(2, array(
    'related' => array(
    'translations' => array(
    'where' => array(
    array('id_lang', '=', 1),
    ),
    ),
    ),
    ));
    [/CODE]
    I get a join from Products and my Products_Translation tables.
    table Products only has 3 ids, no field 'name'
    and I can do this: $product->brand_id = 1337;
    $product->save(); But I can't do $product->name = "12121";
    So how can i have a cascade save, and access and edit fields of the related tables?
    Is it possible at all?
  • Yes, it's possible (I haven't tested the following code, but it should work). $product= Model_Produto::find(2, array(
    'related' => array(
    'translations' => array(
    'where' => array(
    array('id_lang', '=', 1),
    ),
    ),
    ),
    )); // Change the name of product (if product has a column 'name')
    $product_input = array('name' => 'NameOfYourProduct');
    $product->from_array($product_input); // Change column1 and column2 values of the translation of your product (you have only one translation at this moment in the object $product)
    $translation_id = array_pop(array_keys($product->translations));
    $translation_input = array('column1' => 'value1', 'column2' => 'value2');
    $product->translations[$translation_id]->from_array($translation_input); // Cascade save (Product with id=2 and its translation having id_lang=1)
    $product->save(); Let us know if you have problems with this.
  • Thanks a lot Francesco, that works. So that's how I'm suppose to do it, OK, couldn't find it anywhere.
    You've been a great help. On a side note about passing arrays as reference.
    I get this Error Notice, and I googled it, but can't fix it.
    ErrorException [ Runtime Notice ]: Only variables should be passed by reference

    So I googled it and it seems php, doesn't like arrays passed as reference anymore.
    So I changed this:
    $translations_var = $product->translations;
    $translation_id = array_pop(array_keys($translations_var)); But I still get the same notice. Doesn't seem to be affecting my code anymore, but still. Thanks.

Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

In this Discussion