大家好!刚刚加入堆栈溢出,因为它在开始学习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