Ruby on rails 在RubyonRail3中的不同位置进行更新和创建

Ruby on rails 在RubyonRail3中的不同位置进行更新和创建,ruby-on-rails,Ruby On Rails,我打赌其他人也有这个问题,但我没有看到一个好的解决办法 在rails应用程序中,您可能希望使用来自不同位置的一个模型进行操作 比如说,您有一个项目页面,其中列出了所有项目,并有一个用于创建新项目的表单。如果(:id)存在,此表单也可用作更新表单 假设您还有一个“客户展示”页面,其中还列出了某个特定客户的所有项目。在这里,您还需要编辑和创建项目(针对该客户) 当控制器获得此信息时,它将用户发送到respond_to block中指定的页面。但是,有时您希望返回到“项目”页面,有时您希望返回“客户展

我打赌其他人也有这个问题,但我没有看到一个好的解决办法

在rails应用程序中,您可能希望使用来自不同位置的一个模型进行操作

比如说,您有一个项目页面,其中列出了所有项目,并有一个用于创建新项目的表单。如果(:id)存在,此表单也可用作更新表单

假设您还有一个“客户展示”页面,其中还列出了某个特定客户的所有项目。在这里,您还需要编辑和创建项目(针对该客户)

当控制器获得此信息时,它将用户发送到respond_to block中指定的页面。但是,有时您希望返回到“项目”页面,有时您希望返回“客户展示”页面

使用ajax提交时。对于用javascript和ERB填充的项目页面,这不一定适合客户展示页面

有没有一种优雅的方式来处理这个问题,而不需要大量的if语句

编辑

我用两个支架项目和TODO在testapp上做了一些实验

我不认为这是优雅的。对于许多if语句来说,它不是很干燥

我怎样才能让这更好

这是密码

项目/展览

<p id="notice"><%= notice %></p>

<p>
  <b>Name:</b>
  <%= @project.name %>
</p>
<% @todos.each do |todo| %>
<p>

  <%= todo.name %><%= link_to 'Edit', show_path(:id => @project.id.to_s, :todo_id => todo.id.to_s)%>
</p>
<% end %>
<%= render 'todos/form' %>
<%= link_to 'Edit', edit_project_path(@project) %> |
<%= link_to 'Back', projects_path %>
routes.rb的部分内容

match 'projects/:id/project_todo' => 'projects#project_make_todo', :as => :project_make_todo
  match 'projects/:id/:todo_id/project_todo' => 'projects#project_update_todo', :as => :project_update_todo

可以从许多不同位置更新模型的用例可能会因为您提到的原因而令人困惑:哪个控制器处理更新操作;如何设置表格格式,使其适合所有情况?通常,最好的解决方案是创建一个新视图和一个新控制器来处理特殊情况。这样可以使代码更干净,并且不需要使用许多条件

例如,如果您从项目模型和一个项目控制器以及一个简单的编辑和新表单开始,那么您的状态非常好

添加客户模型后,您希望能够修改客户的项目。最好的解决方案是构建一个单独的嵌套表单,用于修改客户的编辑表单和新表单中的项目。这样,您就不会干扰旧的实现,而是要求客户模型负责更新自己的项目

这样,当您从“项目”页面更新项目时,将重定向回“项目”页面,当您从“客户”页面更新项目时,将重定向回“客户”页面


确保在项目模型中保持更新项目的逻辑,这样无论您在哪个控制器中,都可以使用简单的@Project.update\u attributes调用。您不希望在控制器或视图中包含业务逻辑。

可以从许多不同位置更新模型的用例可能会因为您提到的原因而混淆:哪个控制器处理更新操作;如何设置表格格式,使其适合所有情况?通常,最好的解决方案是创建一个新视图和一个新控制器来处理特殊情况。这样可以使代码更干净,并且不需要使用许多条件

例如,如果您从项目模型和一个项目控制器以及一个简单的编辑和新表单开始,那么您的状态非常好

添加客户模型后,您希望能够修改客户的项目。最好的解决方案是构建一个单独的嵌套表单,用于修改客户的编辑表单和新表单中的项目。这样,您就不会干扰旧的实现,而是要求客户模型负责更新自己的项目

这样,当您从“项目”页面更新项目时,将重定向回“项目”页面,当您从“客户”页面更新项目时,将重定向回“客户”页面


确保在项目模型中保持更新项目的逻辑,这样无论您在哪个控制器中,都可以使用简单的@Project.update\u attributes调用。您不希望在控制器或视图中包含业务逻辑。

谢谢您的回答。这将与控制器中的7个RESTfull操作中断。我想这不是问题,但为什么建议坚持7个动作?不建议坚持7个动作。如果您的模型和用例适合RESTful风格,那么建议您使用它,因为其他开发人员更容易理解它。如果您的用例不适合REST操作,那么强制您的代码采用RESTful风格不是一个好主意,因为这只会让人更加困惑。更新嵌套属性并不一定会破坏RESTful路由。您可以更新嵌套模型,但仍然保留在RESTful操作(新建、编辑、更新、创建、索引、显示、销毁)中。谢谢,在尝试将所有内容强制到标准操作中时,我在几个操作中都遇到了令人困惑的代码。我会从7个动作中解脱出来!!谢谢你的回答。这将与控制器中的7个RESTfull操作中断。我想这不是问题,但为什么建议坚持7个动作?不建议坚持7个动作。如果您的模型和用例适合RESTful风格,那么建议您使用它,因为其他开发人员更容易理解它。如果您的用例不适合REST操作,那么强制您的代码采用RESTful风格不是一个好主意,因为这只会让人更加困惑。更新嵌套属性并不一定会破坏RESTful路由。您可以更新嵌套模型,但仍然保留在RESTful操作(新建、编辑、更新、创建、索引、显示、销毁)中。谢谢,在尝试将所有内容强制到标准操作中时,我在几个操作中都遇到了令人困惑的代码。我会从7个动作中解脱出来!!
def project_make_todo
    @project = Project.find(params[:id])
    @todo = @project.todos.build(params[:todo])
    respond_to do |format|
      if @todo.save
        format.html { redirect_to( @project, :notice => 'Todo was successfully created.') }
        format.xml  { render :xml =>  @project, :status => :created, :location =>  @project }
      else
        format.html { render :action => "new" }
        format.xml  { render :xml =>  @project.errors, :status => :unprocessable_entity }
      end
    end
  end

  def project_update_todo
    @todo = Todo.find(params[:todo_id])
    @project = Project.find(params[:id])
    respond_to do |format|
      if @todo.update_attributes(params[:todo])
        format.html { redirect_to(@project, :notice => 'Todo was successfully updated.') }
        format.xml  { head :ok }
      else
        format.html { render :action => "edit" }
        format.xml  { render :xml => @project.errors, :status => :unprocessable_entity }
      end
    end

  end
match 'projects/:id/project_todo' => 'projects#project_make_todo', :as => :project_make_todo
  match 'projects/:id/:todo_id/project_todo' => 'projects#project_update_todo', :as => :project_update_todo