I'm working on a project where we use views to create a interface/layer between another system which is a datasource but have no matching model. This way, in my system, these views are in fact models. Everything is working perfectly fine until now, except for this part:
-------------------------------
|Table |Table |View |
-------------------------------
|Order > |OrderItem > |Item |
-------------------------------
Relation: Order (has many)> OrderItem (has many)> Item.
I recently faced a problem where it tries to save the entire set of relations of a table (the order). The system is supposed to save the order and its items (order-items). But somehow the save ends up hiting an update on the item model which is a view and returns this error, obviously:
Code:
$order->save();
Error:
Data manipulation operation not legal on this view : UPDATE ITEM (...)
Is there a way to track this, forcing it to not occur, or set it as a read only model?
This error occurs in mysql when the view is composed of elements from different tables.
If you edit columns from the same table it's ok but if the same query tries to edit columns for different tables you have an ERROR.
Are you still using Doctrine 1.2?
I think using views with Doctrine was tricky Link
ALso the error can come from the way you declared the relationship on the entities:
Having:
Order Many-to-Many OrderItem Many-to-One Item.
You should make sure take the relationship OrderItem > Item is unidirectional and that OrderItem is the Owning side.
Related
I have the following two models:
stockItem. category
stockItem can have one category and category can have many stockItem.
Incategory there is alway the first category with the id of 1. It can not be deleted.
Now if category with id of 2 gets deleted, all stockItem with the relation to the second category should be updated to the first category.
Is ORM capable of that or do I need to write an own delete function? If so how do I overwrite the delete function?
There is a way to go for this but you must make some modifications.
Laravel has onDelete actions when running migrations. For your problem i think suitable is:
->onDelete('set null');
In order to have this work you will have to change your foreign key (categoryId) to be nullable.
Having done that when you delete a category then all the relations that this category had will be set their field to null, meaning they will belong to category1 which can never be deleted.
This is the approach to do it with pure migrations and this is the closest you can get. That way you will know that when categoryId is null or 1 this stockitem belongs to category1 or was transferred to it cause another category was deleted.
If you really need the id to be 1 then you should use either a helper class that you build yourself, or Laravel Observers.
So, I have a User < ManyToMany > Conversation. What I want to achieve is following.
I want to save 2 User objects(same type, different data) to a Conversation. I know doctrine doesn't duplicate it or it's something wrong with it. I know how it works and understand the workflow. I am just not capable of achieving what I really need.
My code for merging these objects looks like following
$first_user = $this->getDoctrine()->getRepository(User::class)->find($second_user);
$second_user = $this->getDoctrine()->getRepository(User::class)->find($second_user);
$conversation = new Conversation();
$conversation->addParticipator($first_user);
$conversation->addParticipator($second_user);
It currently adds 2 records to conversation and 4 records to conversation_user table. All I need is for it to add one record to conversation and 2 for conversation_user table.
I tried changing the relation to ManyToOne and somehow get it to work, but I failed. I also think it should be done by making use of ManyToMany relationship. Any help appreciated!
I have a database schema that goes like this:
Section
id
name
Subsection
id
name
section_id
Category
id
name
subsection_id
SubCategory
id
name
category_id
Product
id
name
subcategory_id
As you can see, each table has a foreign key that references the previous table. The problem comes when I try to get, for example, the Section from the current product or get all products from one section. So far I have tried this:
Section::with('product')->find(1)->product;
But I get this:
SQLSTATE[42S22]: Column not found: 1054 Unknown column
'product.section_id' in 'where clause' (SQL: select *
from products where products.section_id in
(1))
1 - This makes me think I need to set up a section_id in the products table to make this work. Is this correct?
2 - Shouldn't the Laravel ORM automatically go up the table hierarchy from Product to Section and get the results?
3 - Is there a way to do this maintaining my current table structure, I mean, without adding extra fields in the tables for the foreign keys?
Thanks.
No that is one way to do it but it isn't the only way.
No, how would it know that automatically?
I believe so and you can always create a specific query when laravel relationships don't work for you.
Okay first this assumes you have relationships setup on all the models to access the one below it. If that isn't the case you will need to setup the relationships.
Section::with('subsection.category.subcategory.product')->get();
I've never tried such extreme nesting but I believe this will work. The Laravel Docs talk about eager loading and scroll to see the nested example.
Another item that comes to mind is the hasManyThrough relationship. You couldn't do it for this number deep but it may be something you want to look into.
A brief summary from the docs is taking the first three from your example, Section, Subsection, and Category and then in the section class you would have this relationship.
public function category()
{
return $this->hasManyThrough('Category', 'SubSection');
}
The laravel docs with more information.
I'm stuck in a problem and I can't find a solution to this, it's annoying me.
I've two tables, one called contacts and the other one called phonebooks and they are linked with a third table called *contacts_phonebooks*, this is a many-to-many relationship summarize below:
contacts: id (pk)
phonebooks: id (pk)
contacts_phonebooks: contactid (fk), phonebooksid (fk)
Pretty simple and clear, and it works.
I'm using Laravel 4 and Eloquent ORM, everythings works fine when I've to fetch it, insert it and delete it but when I need to update a contact I fail miserably. I've a form that has a number of checkboxes that represent all the phonebooks (every checkbox has phonebook[] as name) so when you check one of those the phonebook id will be saved in the *contacts_phonebooks* with the contact id.
The problem is that this is not true! I mean when I run this code:
$contact = Contact::find($id);
$contact->contact_name = Input::get('newCName');
$contact->contact_surname = Input::get('newCSurname');
$contact->contact_email = Input::get('newCEmail');
$contact->contact_phone = Input::get('newCPhone');
$contact->contact_birth = Input::get('newCDate');
$contact->phonebooks()->sync(Input::get('phonebook'));
if($contact->save())
{
return "TEST DONE?";
}
It deletes every row in *contacts_phonebooks* associated with the contact id and save only the new one checked... This is weird I know, I try to explain it better.
I want to update Mr.x and he actually is in "Stackoverflow" phonebook, I want to add him in "Nerd" phonebook so I click on update and I selected "Nerd", the other one is already selected.
When I update him the system deletes the "Stackoverflow" link and save ONLY the "Nerd" phonebook (with the code above) this things driving me crazy because Laravel 4 Doc says that you should use the sync() method in order to update a many-to-many relationship.
I don't how how to solve it, I hope you will understand what's my problem.
Cheers.
The documentation says "The sync method accepts an array of IDs to place on the pivot table. After this operation is complete, only the IDs in the array will be on the intermediate table for the model:"
So what I think you are probably looking for is attach().
$contact->phonebooks()->attach(Input::get('phonebook'));
Then you will have to use detach() to remove him from the other.
As stated in the docs: The sync method accepts an array of IDs to place on the pivot table.
Your pivot table should be named
contact_phonebook
and it specifies that in Laravel's documentation.
We are building a core shopping cart that our company will use as a foundation for multiple shopping carts we will build. These are highly specialized, so different product types will require their own tables of data.
For instance, for a cart that sells labels...
product - id | type_id | created
label - id | product_id | x | y | z
We're struggling with how to structure our objects. We'd like to programmatically only interact with the Label class and have the data be "split" so to speak between the two tables. One idea we tossed around was creating a view to use for querying and then just overwriting the object's save() method to actually interact with each table's setters/save functionality.
Has anyone accomplished this or at least faced a similar challenge?
Update: Of course this begs the question... is there a scenario where both tables might have the same column name? And if so, how to handle it.
You can use name/value pair for specialized columns. With "name" part consistent with column names, you can have generalized setter/getter.
Product is related table, so you can interact with it via relation, for instance $labelModel->product. So you have model for each table, as yii suggest. And you can interact only with Label model if you place your functionality at beforeSave(), afterSave() and other methods.