for 循环 - 轨道 3 为特定父级创建新的子项



大家好!刚刚加入堆栈溢出,因为它在开始学习Ruby on Rails 3时是一个有用的资源。

我似乎找不到一个特定的答案,也许我所知道的树错了,但希望你们能在这里整理我。首先介绍一下我正在使用的内容的一些信息:
- 在我的网络应用程序中,我有 2 个模型:一对多关系中的项目和任务.
- 项目有许多任务,任务属于项目
- 任务不是嵌套资源,因为用户需要能够查看所有当前任务,无论它们适用于哪个项目.
- routes.rb 因此现在看起来像这样:
资源 :p
资源 :任务

在项目显示视图中,我显示与该项目关联的任务列表。 下面是一个link_to,用于创建一个看起来像 <%= link_to "新任务",new_task_path,:class => "new-btn" %>。link_to将用户带到新视图以创建新任务。呈现的_form视图以以下格式开头:<%= form_for(@task( do |f|%>.

现在,我认为我需要将项目 ID 从项目显示视图传递到新的任务视图:但是,这就是我迷路的地方,可能有点混淆。

有人可以指出我正确的方向:也许是概述执行此操作所涉及的所有步骤的资源,或者甚至可能在此处提供该过程所涉及的步骤的概述。

非常感谢!

您可以创建嵌套路由,并且仍然可以显示所有任务,而不管项目如何。只需确保稍后定义了任务资源,例如

resources :projects do |p|
  resources :tasks
end
resources :tasks

现在在项目索引或显示视图中,您可以创建链接,例如

link_to 'New Task', new_project_task_path(project)

任务索引视图可能有点棘手。一切都取决于您如何对这些任务进行排序。例如,如果您显示按项目排序的它们,那么您可以创建一个链接,例如

link_to 'New Task', new_project_task_path(task.project)

至于形式。在新操作中,您必须从参数中获取id并将其放入任务对象中

if (params[:project_id])
  @task.project_id = params[:project_id]

在表单视图中,您可以创建将保存此值的隐藏字段

f.hidden :project_id

这将使它工作,但如果不提供项目,您将无法转到新任务。更好的解决方案是创建一个包含所有项目的选择字段。为此,您应该执行以下操作:

在模型/项目.rb

def getProjectsList
  projects = Project.all
  projects.map do |p|
    [project.name, project_id]
  end
end

在控制器/application_controller.rb 中

def find_projects
  @projects = Project.new.getProjectsList
end

在控制器/tasks_controller.rb 中开头

before_filter :find_projects, :only => [:new, :edit, :update, :create]

在视图/任务/_form

f.select :project_id, @projects

这样,您始终可以选择项目,如果参数中给出了一个项目,则它已经被选中了

如果current_user返回 User 对象,那么您应该能够调用

current_user.projects 

以获取所有用户的项目。

定义用户和任务之间的关系可能有效(尽管我不确定这一点(。

#models/user.rb
has_many :projects
has_many :tasks, :through => :projects

在这种情况下,只需

current_user.tasks 

应返回用户的任务

有很多方法可以做到这一点。一个简单的方法可能是将参数添加到您的链接并在控制器中使用它:

在您看来:

<%= link_to 'New Task', new_task_path(:project_id => @project.id), :class => "new-btn" %>

在任务控制器中:

def new
  @task = Task.new(:project_id => params[:project_id])
end

将项目 ID 从项目页传递到"新建任务"页的一种方法是将其添加到 url 上的查询字符串中。 示例 HTML 如下所示:

<a href="/tasks/new?project_id=123" class="new-btn">New Task</a>

要让 Rails 生成该 HTML,您可以在 ERB 中执行此操作:

<%= link_to 'New Task', new_task_path(:project_id=>@project.id), :class => "new-btn" %>

接下来,您需要将项目 ID 从"新建任务"页传递到实际创建任务的操作。 一种方法是在表单中创建一个包含项目 ID 的隐藏输入,以便在提交表单时将其与其他参数一起传递。 HTML 将如下所示:

<input type="hidden" name="project_id" value="<%= params[:project_id] %>" />

要以 Rails 方式执行此操作,您可以在 TasksController 的新任务操作中设置项目 ID:

@task.project_id = params[:project_id]

然后在 form_for 块内的视图中执行类似操作(我对语法不是 100% 确定(:

<%= f.hidden_field(:project_id) %>

哇!感谢所有很棒的信息家伙!通过这个,我确实学到了一些巧妙的技巧。

这是我现在的工作:

路线.rb

资源:p rojects do |p|     资源 :任务 结束 资源 :任务

我真的很高兴得知这部分是可能的。现在,我可以享受嵌套资源的好处,但也使用原始的非嵌套路由执行任务。
显示项目视图中的link_to

<%= link_to 'New Task', new_project_task_path(@project), :class => "new-btn" %>

tasks_controller.rb 新操作

if (params[:project_id])
      @task.project_id = params[:project_id]
    end

新建任务表单隐藏域

<%= f.hidden_field :project_id %>

这一切都非常适合向项目添加新任务:但是,显示与当前用户相关的所有项目相关的所有任务的列表有点棘手,我想知道是否有比我想出的更好的方法:

索引操作中的 tasks_controller.rb

@projects = Project.find_all_by_user_id(current_user)
@tasks = Array.new
@projects.each do |p|
    p.tasks.each do |t|
        @tasks << t
    end
end

我正在使用"设计"和"cancan"宝石进行用户管理(两者都很棒!上面的"current_user"正是您所期望的:当前登录的用户。这是一个合理的解决方案,还是有更好的方法来为用户获取所有任务?

以防万一:

User has_many Projects, and Project has_many Tasks

最新更新