cakephp 2 - trying to save into a joining table - cakephp

I have these DB tables:
volunteers
services
services_volunteers
I baked the models, controllers and views. Now in a particular function in the volunteers controller I want to access the service_volunteers model to create a record so I do:
$this->loadModel('ServicesVolunteer');
$this->ServicesVolunteer->create();
$this->ServicesVolunteer->save(array('ServicesVolunteer'=>array('ServicesVolunteer.volunteer_id'=>$this->Volunteer->id, 'ServicesVolunteer.service_id'=>$id)));
However this isn't working for some reason. I'm stuck coz I'm pretty sure I've done similar things plenty of times before and I can't see what's going wrong. I've tested and it looks like the model loads ok, but if I wrap the create() method in an IF statement I can see it doesn't seem to fire
anyone any ideas? would be gratefully received!

Related

What does $this->Model1->Model2 accomplish in CakePHP HABTM?

Basically, I've implemented the HABTM successfully in CakePHP, but the trouble is, I don't understand why it works.
The thing I hate about the CakePHP cookbook is that is tells you what to do but make very little effort to explain the underlying segments of their code.
Essentially, my data model is like this.
Task HABTM Question
I don't understand this code fragment.
$this->set('questions', $this->Task->Question->find('list'))
In particular, what is $this->Task->Question supposed to accomplish?
Also how is the above code link to this code fragment in the view?
echo $this->Form->input('Question');
One thing that is very peculiar is that with the above code fragment, I get a multiple select option.
However, if I change the code to this,
echo $this->Form->input('question');
I get a single select drop down list.
I scoured the entire documentation and still cannot find a satisfactory explanation to my doubts.
Would really appreciate if anyone can clarify this issue for me.
1. Model chaining
When a model has an association to another model (like in your example an HABTM one) then you can call methods of the associated model by chaining it to the current model. This is explained early in Associations and an example of exactly how it works is given at the end of the first section.
When you are someplace in your TasksController normally you would expect that only your Task model would be available. Instead any association described in the Task model is chained to that model in the form of $this->Model1->Model2.
So $this->set('questions', $this->Task->Question->find('list')) means:
From current model Task that you know about, access the associated model Question and then call its find('list') method. Then $this->set the results to the view as variable questions.
2. FormHelper Conventions
When you use a CamelCased single name for field input, like in $this->Form->input('Question'); you are saying to FormHelper that the data contained in the questions variable come from a model named Question with a HABTM association, therefore they should be handled as a multiple select (as HABTM points to such an association).
With a field name of model_id, like in this example question_id, you're asking for a single select (select a single id of the connected model).
With anything else, FormHelper looks at the field definition and takes the decision itself, but of course your can override any default behavior you want using options.
This is explained in detail and I'm surprised you missed both. CakePHP has one of the best documentations available, almost everything you need is there.

Why Do Some Related Entities Persist and Not Others in RIA Services?

I'm having a lot of troubles with RIA Services. I'm really wondering if it's worth the hassle at all. The problem I have now is similar to other problems: related entities. Let's say I have a class, Foo. Foo has two related entities, Bar and Fighter.
If I'm working on a new Foo, foo, and I want to add something to the Bars collection, it works just fine. Like:
foo.Bars.Add(new Bar{A=a, B=b});
But when I try to add a Fighter, it doesn't work:
foo.Fighters.Add(new Fighter{C=c,D=d});
I've been all around the interwebz looking for the solution. I've found the suggestions to use the [Include] attribute and the [Associated] attribute as well. Both have worked in some cases. But they're not working in this case and I have zero clue why. I've deleted and re-created my EDMX and my DomainService because someone suggested it, but it isn't working.
So what is wrong and what other information do you need to help me out? When I say try to add a Fighter to my foo.Fighters collection, it's not persisting the add. I will note that I'm trying to add an existing Fighter in my specific example, not a new Fighter, if that helps/gives clues.
If you need information or real code samples, I'll be happy to oblige. Thanks in advance to all that try to help.
A number of things to check and confirm
The Fighter table has a foreign key defined in the database.
Use [Association], [Include], and [Composition] attributes. Association defines the relationship. Include instructs the server to send the instance or contents of the collection to the client, if populated. Composition instructs WCF RIA to track changes to the collection and send them back to the server.
Ensure you are calling context.SubmitChanges() after all the adds in Silverlight.
Ensure you have an insert method on your DomainService.
Maybe one or more of these will help.

HABTM and belongsTo at the same join, cakePhp

I have a model Fix with a relationship HABTM Device model.
Device model has a belongsTo to Device_type model, like this, for only getting the device type name:
var $belongsTo = array('Device_type'=>array('fields'=>'name'));
So, I need every Fix, its devices and its Device_types. When I make a Fix->find('all', array('recursive' => 2))
I expect to get every Device related to Fix (this works ok) and ALSO for every device, its Device_type.name (which is not working).
This is what I get instead for every Device in the result (an empty array):
["Device_type"]=>
array(0) {
}
Besides this, when I make this query for testing: Fix->Device->find('all'), it returns the current Device_type.names for every device related to fixes, which means models are related propertly.
Any help? Thanks.
First thing I notice, is your naming conventions should be lower case under_score for your multi-word table names.
And its also apparent your relationships most likely are not set up correctly if you are not getting the data on a recursive 2.
It's kind of hard to make more judgement with your limited code.
If you are new to CakePHP and MVC, it would be really best to follow the blog tutorial on the CakePHP web site. From that, you will learn the basics of building a CakePHP app and in the end have working application which you can "play" with and modify to learn how MVC ticks. You can experiment and learn a lot from this : )

cakephp calling different controllers in one view?

I can't seem to find a method to call different controller in the same view. The closest thing I've found is $html->link("Register User",array('controller' => 'users', 'action'=>'register')).
So I did the cakephp's blog tutorial. I have a posts_controller.php, and now I want to add in a star rating system. I googled some stuff and got this nifty-already-been-done rating system you can download: http://www.reversefolds.com/articles/show/rating2
Now I have two controllers, rating_controller.php and post_controller.php.
My base route, '/', is pointing to post controller's index action. My post's view.ctp is showing one blog entry, I want to add in the rating system within this view. And to use the rating I need to call the helper like so:
echo $rfRating->ratingBar($ratingInfo);
When I do this in post's view.ctp file. It complains. I've tried messing around with var $helpers = array('blah') but it didn't work, I just end up merging the rating controller in the post_controller, which I think is stupid. I can use the rating system for other stuff too.
So... I don't know what to do. Actually that's a lie, I think I two idea how to tackle this. But I need critiques and other solutions that my google skills have failed.
Should I just implement the whole rating system into the app_controller.php instead? So that every controller inherit this rating system? Sounds stupid because I don't think my user registration needs the rating system.
I've googled up another solution, requestAction('blab'). I think what this enable me to do is... to call another controller within a controller. But this is frown upon cause it kills performance. And I don't exactly know how to do this haha or if it works. I call the rating controller but what about its helper function? Maybe it'll recognize it if I add a var $helpers = array('rating');
Anyway, thank you all in advance for taking the time to read this. Please point me in the right direction.
Have the ratings_controller extend the posts_controller.
This gives you the ability to selectively decide which pages need the ratings module.

Why am I getting an undefined property error when my relationships seem correct?

I'm having a slight problem that I can't figure out, but should be really simple.
I have the following model structure in my cakePHP (1.3) app:
ProspectiveQuote [hasMany] QuoteUnit [belongsTo] Unit
but in my ProspectiveQuotesController the line:
$this->ProspectiveQuote->QuoteUnit->Unit->find('list');
gives me the following error:
Undefined property: AppModel::$Unit
Of course, it shouldn't be looking at AppModel, it should be looking at QuoteUnit.
If I do $this->ProspectiveQuote->QuoteUnit->find('all') it seems to get results (allbeit without any related model data...) so it obviously finds the QuoteUnit well enough, and I have double-checked its relationship with Unit, and it all seems fine...
Seems like a simple enough problem. From what I can see people with this problem usually have their model names wrong (or plural) but this is not the case here...
What could I be doing wrong?
I would say to double check over the syntax of your model associations to make sure they are correct. Or back them up, and bake out some new models to test with, just to ensure that it's how you expect it.
Another great thing is to grab the DebugKit http://www.ohloh.net/p/cakephp-debugkit Which will help you to see your variables and your sql queries.
As mentioned in Leo's comment I would try and avoid uses() as it puts, or did put in 1.2 a bit of a big overhead onto your stack.
Have you set var $uses = array('ProspectiveQuote','QuoteUnit','Unit'); in your controller? (although there are slightly more efficient ways of doing this) - see http://book.cakephp.org/2.0/en/controllers.html#controller-attributes
If you do this you can access your associated models like:
$this->Unit->find('list');
or
$this->ProspectiveQuote->QuoteUnit->Unit->find('list');
I know which I prefer.

Resources