Reputation: 2893
I have a database design like the following
Poll
id | name
--------------
1 | Poll One
PollQuestion
id | poll_id | question
-------------------------
1 | 1 | Something
PollAnswer
id | question_id | answer
-------------------------------
1 | 1 | Answer 1
-------------------------------
2 | 1 | Answer 2
-------------------------------
3 | 1 | Answer 3
A Poll can have One PollQuestion, and a PollQuestion can have many PollAnswer's.
This all works fine, I can create Polls, questions and answers. This is all done within a backend which requires you to log in as an admin user.
On the frontend, I need to display the Poll Question and possible answers. I set up a PollResponse Model to which a Poll can have many PollResponse. Models look something like this
class Poll extends Model
{
public function pollQuestion()
{
return $this->hasOne('App\PollQuestion', 'poll_id');
}
public function pollResponse()
{
return $this->hasMany('App\PollResponse', 'poll_id');
}
}
class PollResponse extends Model
{
public function poll()
{
return $this->belongsTo('App\Poll');
}
}
I then have my routes set up like this following
Route::group(['middleware' => ['web']], function () {
Route::model('polls.response', 'PollResponse');
Route::resource('/', 'PollResponseController', ['except' => ['create', 'show', 'edit', 'update', 'destroy']]);
Route::group(['middleware' => ['admin_logged', 'can_see']], function ()
{
Route::model('polls', 'Poll');
Route::bind('polls', function($value, $route) {
return App\Poll::whereId($value)->first();
});
Route::resource('admin/polls', 'PollController');
Route::model('polls.questions', 'PollQuestion');
Route::resource('polls.questions', 'PollQuestionController', ['except' => ['index', 'create', 'show', 'edit', 'destroy']]);
});
});
So the idea is, a normal user can visit the main domain and see the latest poll question with its possible answers. They then select an answer and submit their response. The view for this is like the following
<div class="panel-heading">
<h3 class="panel-title"> {{ $question->question }}</h3>
</div>
<div class="panel-body">
{!! Form::model(new App\PollResponse, ['route' => ['store', $poll->id]]) !!}
@if (count($answers) !== 0)
@foreach($answers as $key => $value)
<div class="radio">
<label>
<input type="radio" name="optionsRadios" value="{{ $value->answer }}"> {{ $value->answer }}
</label>
</div>
@endforeach
@endif
{!! Form::submit('Save', array("class"=>"btn btn-info pull-right ")) !!}
{!! Form::close() !!}
</div>
So this all works fine. I am having a problem with the store function though within my PollResponseController. If I submit the response, the poll_id is added to the URL as defined within the route. But in the store function, I am currently doing
public function store(Request $request, Poll $poll)
{
dd($poll);
}
I would expect this to output the current Poll Object, but it is currently outputting an empty Poll Object. How can I get the related Poll Object into this function so I can relate the responses to a particular Poll?
Thanks
Upvotes: 0
Views: 56
Reputation: 567
I bet it's because of this line:
Route::resource('/', 'PollResponseController', ['except' => ['create', 'show', 'edit', 'update', 'destroy']]);
The first parameter expects of the resource method expects the resource name (i.e. "polls" or "polls.response").
I wonder what you wanted to achieve with that call, but if you want to register a store route to "/store" your only way is to define a regular route like this:
Route::post('store/{polls}', 'PollResponseController@store');
That is because laravel's restful resources always have to have some kind of base path, you can not put them into the root of your domain (example.com/{id}, example.com/{id}/edit, example.com/store/{id}, etc.)
The alternative is to provide resource name like this:
Route::resource('polls.response', 'PollResponseController', ['except' => ['create', 'show', 'edit', 'update', 'destroy']]);
But you'll have to change your form urls accordingly.
I'd also check this line:
{!! Form::model(new App\PollResponse, ['route' => ['store', $poll->id]]) !!}
Assuming that 'polls.response' is registered resources You might need to pass 'polls.response.store' as a route name.
Upvotes: 1