Rails 3为特定父级创建新子级

时间:2011-05-29 18:12:17

标签: ruby-on-rails-3 for-loop parent

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

我似乎无法找到一个特别的答案,也许我正在为我所知道的所有人咆哮错误的树,但希望你们这些人可以把我排除在外。首先是一些关于我正在使用的信息:
  - 在我的网络应用程序中,我有两个模型:一对多关系中的项目和任务   - 项目有很多任务,任务属于项目
  - 任务不是嵌套资源,因为用户需要能够查看所有当前任务,无论他们用于哪个项目。
- routes.rb因此现在看起来像这样:
资源:项目
资源:任务

在项目展示视图中,我显示与该项目相关的任务列表。下面是一个link_to,用于创建一个看起来像<%= link_to'New Task',new_task_path,:class =>的新任务。 “new-btn”%>。 link_to将用户带到新视图以创建新任务。渲染的_form视图以:<%= form_for(@task)do | f |开头%GT;

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

有人可以指出我正确的方向:也许是一个资源概述了这样做所涉及的所有步骤,或者甚至可以提供这里过程中涉及的步骤的大纲。

非常感谢!

5 个答案:

答案 0 :(得分:1)

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

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)

表格。在新操作中,您必须从params获取id并将其放入任务对象

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

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

f.hidden :project_id

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

in models / project.rb

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

in controllers / application_controller.rb

def find_projects
  @projects = Project.new.getProjectsList
end

的controllers / tasks_controller.rb中的

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

在views / tasks / _form

f.select :project_id, @projects

通过这种方式,您始终可以选择项目,如果在参数中有一个已经选择了

答案 1 :(得分:1)

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

current_user.projects 

获取所有用户的项目。

定义用户和任务之间的关系可能有效(虽然我不确定这个)。

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

在这种情况下只需

current_user.tasks 

应该返回用户的任务

答案 2 :(得分:0)

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

在您看来:

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

答案 3 :(得分:0)

将项目ID从项目页面传递到“新建任务”页面的一种方法是将其添加到网址上的查询字符串中。示例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) %>

答案 4 :(得分:0)

哇!感谢所有优秀的信息!我肯定学到了一些巧妙的技巧。

以下是我现在的工作:

routes.rb

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

我很高兴得知那部分是可能的。现在我可以享受嵌套资源的好处,但也可以使用原始的非嵌套路径来完成任务
show project view中的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