Create and show items in the samve view
While trying to build a form to create new items on an index page rather than the new view, i ran into a curious problem.
When presenting the form for creation of a new task in the current project, the @tasks variable that contains the tasks that are supposed to be displayed in the list below, seems to be empty. Therefore i get a "No route matches" since the object im passing to ie. complete_project_task_path is nil.
When removing the form, everything works like a charm. Any ideas why this happens?
<h1>Listing tasks</h1>
<%= form_for([@project, @project.tasks.build]) do |f| %>
<div id="new_quick_task">
<%= f.text_field :title, :value => 'Quickly add a new task' %>
<%= f.submit %>
</div>
<% end %>
<div id="task_list">
<% @tasks.each do |task| %>
<div class="task">
<div class="completed"><%= task.completed %></div>
<div class="complete_link"><%= link_to "Good", complete_project_task_path(@project, task) %></div>
<div class="title"><%= link_开发者_运维知识库to task.title, project_task_path(@project, task) %></div>
</div>
<% end %>
</div> <!-- end task_list -->
Why do you use @tasks
and not @project.tasks
? because it would show the new task you created for your form?.
Well, you could still use @project.tasks
and do something like:
<% @project.tasks.each do |task| %>
<% unless task.title.nil? %>
<div class="task">
<div class="completed"><%= task.completed %></div>
<div class="complete_link"><%= link_to "Good", complete_project_task_path(@project, task) %></div>
<div class="title"><%= link_to task.title, project_task_path(@project, task) %></div>
</div>
<% end %>
<% end %>
which would skip the tasks without the title.
The error you get is not because the @tasks
variable is empty, because if it was, you would never come to the code below it. The error you get is that one of the items inside your @tasks
contains a value it does not expect. I guess it has something to do with your complete_project_task_path(@project, task)
that will check something of task
that is not set correctly?
So i think i figured it out. (please correct me if im wrong)
Ruby variables hold references to objects and the = operator copies the references.
(from http://ruby-doc.org/docs/Newcomers/ruby.html#objects no. 17)
Taking that into account, look at the following example
@task_list = @project.tasks
This essentially makes @task_list
refer to the same object as @project.tasks
. If the data in @project.tasks
changes, so does @task_list's
data because they both point to the same object.
@project.tasks.build
seems to alter the object, that both @project.taks
and @task_list
point to, in some way.
The solution was pretty simple. Instead of setting @task_list = @project.tasks i created a new object for @task_list.
So in the controller, istead of doing this:
@project = Project.find(params[:project_id])
@task_list = @project.tasks
just do it like this:
@project = Project.find(params[:project_id])
@taks_list = Task.where(:project_id => @project.id)
精彩评论