我似乎无法找到一个特别的答案,也许我正在为我所知道的所有人咆哮错误的树,但希望你们这些人可以把我排除在外。首先是一些关于我正在使用的信息:
- 在我的网络应用程序中,我有两个模型:一对多关系中的项目和任务
- 项目有很多任务,任务属于项目
- 任务不是嵌套资源,因为用户需要能够查看所有当前任务,无论他们用于哪个项目。
- routes.rb因此现在看起来像这样:
资源:项目
资源:任务
在项目展示视图中,我显示与该项目相关的任务列表。下面是一个link_to,用于创建一个看起来像<%= link_to'New Task',new_task_path,:class =>的新任务。 “new-btn”%>。 link_to将用户带到新视图以创建新任务。渲染的_form视图以:<%= form_for(@task)do | f |开头%GT;
现在,我认为我需要将项目ID从项目展示视图传递到新任务视图:但是,这是我迷路的地方,可能有点混乱。
有人可以指出我正确的方向:也许是一个资源概述了这样做所涉及的所有步骤,或者甚至可以提供这里过程中涉及的步骤的大纲。
非常感谢!
答案 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