在samve视图中创建和显示项目

时间:2010-11-28 19:47:04

标签: ruby-on-rails ruby-on-rails-3

在尝试构建表单以在索引页面而不是新视图上创建新项目时,我遇到了一个奇怪的问题。

当在当前项目中呈现用于创建新任务的表单时,包含应该在下面列表中显示的任务的@tasks变量似乎是空的。因此,我得到一个“无路由匹配”,因为对象即时通过ie。 complete_project_task_path为零。

删除表单时,一切都像魅力一样。任何想法为什么会这样?

<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 -->

2 个答案:

答案 0 :(得分:1)

为什么使用@tasks而非@project.tasks?因为它会显示您为表单创建的新任务?

好吧,您仍然可以使用@project.tasks并执行以下操作:

<% @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 %>

会跳过没有标题的任务。

您得到的错误不是因为@tasks变量为空,因为如果是,您将永远不会看到它下面的代码。您得到的错误是@tasks中的一个项目包含一个它不期望的值。我想这与complete_project_task_path(@project, task)有关,会检查task未正确设置的内容吗?

答案 1 :(得分:0)

所以我想我想通了。 (如果我错了,请纠正我)

  

Ruby变量包含对引用的引用   对象和=运算符复制   引用。

(来自http://ruby-doc.org/docs/Newcomers/ruby.html#objects第17号)

考虑到这一点,请看下面的例子

@task_list = @project.tasks

这实质上使@task_list引用与@project.tasks相同的对象。如果@project.tasks中的数据发生变化,@task_list's数据也会发生变化,因为它们都指向同一个对象。

@project.tasks.build似乎改变了@project.taks@task_list以某种方式指向的对象。

解决方案非常简单。我没有设置@task_list = @ project.tasks,而是为@task_list创建了一个新对象。

所以在控制器中,不要这样做:

@project = Project.find(params[:project_id])
@task_list = @project.tasks

就这样做:

@project = Project.find(params[:project_id])
@taks_list = Task.where(:project_id => @project.id)