What is the method to save and update Many to Many relationship in Yii framework?
There is a better implementation as behavior.
http://www.yiiframework.com/forum/index.php?/topic/6905-please-test-my-ar-enhancement-automatically-sync-many-many-table-when-calling-save/
Unless you create a model for the table between the two main tables, your only option is to use DAO (Database Access Object) and specify SQLs with it.
Have a look at how blog demo accomplishes this task.
use MANY_MANY relationship type to setup many to many connection between Models (An associative table is needed to break a many-to-many relationship into one-to-many relationships)
And now you can use all relational functions of Active Records
Yii Framework - The Definitive Guide to Yii: Working with Databases-Relational Active Record
The following extension does what you want...
Yii Framework - Extension: cadvancedbehavior
An important thing to note: On each update, the extension clears all previous records and creates new ones. So I wouldn't use it when the intermediatry table contains extra data other than the foreign keys.
you could set that up in mysql level..by going to relational view under each table in phpmyadmin and provide necessary relational condition..and use MANY_MANY in the model class inside relations..
The question is too common.
Usually data components with MANY to MANY relationships appear sequentially and independently. So you just need to do one insert action after another.
If your relationship needs dependent update you should user SQL triggers on the DataBase level. That'll ensure integrity of data and give a quite good separation in business logic of the application.
CREATE TRIGGER some_trigger
AFTER UPDATE ON some_table
...
END IF;
A similar way is to incapsulate relational data in one logical model on PHP level (and e.g. manipulate with 2-3 AR models there) and emulate SQL triggers logic in it.
Related
I'm doing a web app here using Laravel + AngularJS and I have a question.Do I need a model for each table that I have in my database? There are 87 tables in my database and I need to query all of them according to with the input that the User wants.
I just want to make sure with all tables must have a model file or if just one is enough.
There are 2 ways by which you can access your DB tables:
Eloquent ORM (dependent on Models)
DB Facade Query Builder(independent on Models)
Former, is more clean and best approach to perform DB query and related task, whereas latter is not clean, and it is going to be difficult for you to manage large application, as you told there are 80+ tables in your application.
Also, if you're using Eloquent way, then it's also a better to have a base model, which will have common code which you can inherit in child models. Like if you want to store "user id" who did some DB changes, then in the boot function, you can write Auth::id() and assign that value to changed_by field on your table.
In DB Facade way, you've to hard code table name every time you're performing DB operation, and which leads to inconsistency when you found that you've to change the name of the table, it's a rare scenario still it'll be difficult to manage if in a file there are multiple tables DB operation going on. There are options like, creating a global table name variable which can be accessed to perform DB operation.
Conclusion:
Yes, creating 80+ model for implementing Eloquent way is painful, but for a short term, as the application grows it will be easy for you to manage, it will be good for other developer if they start working on it, as it will give a overview of DB and it will improves code readability.
It depends on how you'd like to handle queries.
If you'd like to use Eloquent ORM, you need model classes to handle objects and relationships. That is a model for a table, except intermediate relationship tables, which may be accessed through pivot attribute.
Raw SQL queries are also supported. You don't really need model classes for them, as each result within the result array will be a PHP StdClass object. You need to write raw SQL though.
See Laravel documentation.
I have few lookup tables which are listed below. As of my understanding we need a Model for each database table, but does this also apply to lookup / mapping tables? what is the best practice used while creating models? Below is a sample of my lookup tables...
Transaction Customer Transaction_Lookup
id Id transection_id
date name customer_id
active active
I have created models corresponding to Transaction and Customer tables, do I need to create a corresponding model for Transaction_Lookup as well?
Also I am using Data Mapper pattern which means I will also have to create a Mapper class for each model...
Thanks for your help in advance....
One remark I would make is to not think of models as corresponding one-to-one with tables. That can be very limiting in your OOP design. That said it is true often your models will align to a single table. Look-up tables being an obvious scenario where this is true.
As for needing a concrete model for each lookup table... I would consider writing a generic Model that could be used for all objects corresponding to 'lookup' tables. You could then use that generic class, or write it as an abstract and extend it and create named concrete classes. The amount of unique code needed there could be very limited, leveraging what you already have on the parent class. If you wanted a look up table specific abstract you could abstract the fields key(id), value, friendly name, active? and map the corresponding fields on the tables to those generic properties. Really a number of ways to go about that, hope I explained it well.
I typically write two styles of mappers, ones that are essentially table row gateways like Zend_Db_Table and another that is more custom, where perhaps I use a stored procedure or complex Zend_Db_selects joining off multiple tables. Using the table row gateway style mappers I usually just need to specify a table name, adapter, and mapped object for the mapper to work with. On the custom mappers I usually need to write more of the implementation code from scratch on a case by case.
I like this approach of using a Data Mapper. Can be both convenient and powerful.
I'm in the process of writing a very light-weight ActiveRecord implementation in PHP. I have the basics working, but I want to implement eager loading of at least the one-to-one relationships. I've been brainstorming on a clean way to do this.
If I'm eager loading a single one-to-one relationship, I will have to know the columns for both tables and will have to alias the columns following some convention that will allow me to map the results back into the correct objects.
I'm looking for suggestions on how to alias the columns from each table such that mapping them back to their respective objects is as painless as possible.
My initial thoughts are to alias the base table's columns as "base_column_name" and the related tables columns as "user_email" (if "User" is the name of the related object). Is there a better way to do this that I'm overlooking?
A second option I have considered is to get all of the objects off of the base table, and then gather the related objects in one "WHERE IN" using the keys from the base table. But, would this cause performance problems?
CakePHP uses php's flexible associative arrays in its ActiveRecord implementation. So a one to many relationship could be
array('Tablename'=>array('columnname'=>'columnvalue'),
'AssociatedTable'=>array('0',
array('columnname'=>'columnvalue')));
It does put one more layer in everything so you have to do $data['tablename']['columnname'];
i am using Zend Framework to build a web interface for setting up ACL - permission rights - for users of a custom CMS. Since the ACL data is spread in 5 tables(users, groups, permissions, urls=action+controller, nice permission name for the user to understand) and i have only one controller with the four basic CRUD(create, list, update, delete) operations i was wondering what is the best way to do it?
All the examples in my books i've seen that each model extend Zend_Db_Table_Abstract and thus represents one table.
I was thinking i have to do a model that doesn't extend zend_db_table_abstract and then write the queries that i need by hand thus limiting myself to mysql database only?
p.s. please do not argue over the acl database structure
thank you
The definition of the Table Data Gateway pattern is
An object that acts as a Gateway to a database table. One instance handles all the rows in the table.
That's why you won't see it used any differently in Zend Framework. It's a Data Source Architectural Patterns while the thing you are asking about is a Domain specific class.
What you are encountering is Impedance Mismatch, meaning your Business Objects dont match the structure of your Database Design. The common solution is to use a DataMapper or an ORM to handle that for you.
The other solution would be to create a View in your database that joins the tables in a way that maps 1:1 to your required business objects. Then add a Zend_Db_Table for that view. You'd still have to come up with custom create, update, delete logic though. That's not data mapping though, but if you don't have any Business/Domain classes to map to, it's fine.
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