【问题标题】:How to update different columns on different views on Rails 4 for the same Model?如何为同一模型更新 Rails 4 上不同视图的不同列?
【发布时间】:2016-05-03 09:05:54
【问题描述】:

我有 2 个模型。

Scoreboard Model : can have many teams 
Team Model : belongs to Scoreboard

Teams has the follow columns: 
name: string
win,loss,tie: integer

在 Team#Index 视图中,我收集了与记分牌相关的所有团队。同样在该页面上,我可以在每个团队对象的顶部呈现一个编辑表单并通过 ajax 对其进行更新。以下是相关代码:

团队#索引视图:

<div class="team-list">
    <%= render @teams.reject(&:new_record?) %>
</div>

_team.html.erb

  <div class="row team-div" id="team_<%=team.id%>">

   <%= link_to (scoreboard_team_path(@scoreboard, team)) do %>
      <div class="col-xs-4 team-div-1"> <%= team.name %> </div>
   <% end %>

   <%= link_to (edit_scoreboard_team_path(@scoreboard, team)), remote: true, class: "team-edit-link" do %>
           <div class="col-xs-6 team-data">
            <div class="row">
                <div class="col-xs-4 team-div-2"><%= team.win %> </div>
                <div class="col-xs-4 team-div-2"><%= team.loss %> </div>
                <div class="col-xs-4 team-div-2"><%= team.tie %></div>
            </div>
           </div>
  <% end %>

</div>

如您所见,我有一个可用的编辑链接,它通过 ajax 呈现一个编辑表单来代替有问题的 team object。编辑表单仅更新 win,loss,tie 列。

编辑呈现的表单:

<%= form_for [@scoreboard, @team], remote: true do |f| %> 

     <div class="row team-edit-form">
        <div class="col-xs-4 edit-team-1">Placeholder</div>


        <div class="col-xs-2 edit-team-2"><%= f.number_field :win, min: 0, max: 9999, class: "form-control", placeholder: "0"  %></div>


        <div class="col-xs-2 edit-team-2"><%= f.number_field :loss, min: 0, max: 9999, class: "form-control", placeholder: "0" %></div>

        <div class="col-xs-2 edit-team-2"><%= f.number_field :tie, min: 0, max: 9999, class: "form-control", placeholder: "0" %></div>

        <div class="col-xs-2 edit-team-3"> <%= f.submit "Done", :data => {:disable_with => "Saving..."}, class: "btn btn-primary" %></div>
     </div>
 <% end %>

Team#update 控制器方法(通过 ajax 重新加载新编辑的团队对象 div):

def update
    @scoreboard = Scoreboard.find(params[:scoreboard_id])
    @team = @scoreboard.teams.find(params[:id])
    if @team.update_attributes(team_params)
     respond_to do |format|
         format.html {redirect_to scoreboard_teams_path(@scoreboard)}
         format.js
     end
    else
      respond_to do |format|
         format.html {redirect_to scoreboard_teams_path(@scoreboard)}
         format.js { render action: "update_error" }
     end
    end
 end 

现在解决我的问题。以上所有都发生在 ajax 的 team#index 视图上。 在 team#show 视图上,我想只编辑没有 ajax 的团队名称。

到目前为止,这是 team#show 视图的样子:

团队#show 视图

<h3> <%= @team.name %> <h3>

<%= form_for [@scoreboard, @team] do |f| %>

        <div class="col-xs-4"><%= f.text_field :name, required: true, maxlength: 30, class: "team-name-field form-control", placeholder: "Enter name"  %></div>

        <div class="col-xs-1"> <%= f.submit "Update", :data => {:disable_with => "Saving..."}, class: "btn btn-primary" %></div>

<% end %>

提交后,我想更新名称,然后将页面重定向回 team#show(不需要 ajax)。目前,此表单也路由到相同的更新方法。是否可以使用相同的更新方法但对 team#show 视图执行不同的响应代码?如果没有,我如何在 team#show 页面上提交表单时执行自定义更新代码?

【问题讨论】:

    标签: ruby-on-rails activerecord


    【解决方案1】:

    我不确定您是否可以使用不同的 response_to,因为您只能在操作中重定向或呈现一次。

    一种方法是创建一个新的路由/控制器方法来更新团队名称。

    路线

    resources :teams do
      member { post 'update_name' }
    end
    

    show.html.erb

    在视图中,你可以发布到上面的路由,在控制器中,为新路由创建一个方法。

    <%= form_for @team, :url => update_name_team_path(@team)
    

    teams_controller

    def update_name
      @team = Team.find(params[:id])
      redirect_to team_path(@team)
    end
    

    【讨论】:

    • 我的正常更新方法真的很混乱,所以我一直在寻找这样的东西。除了post 对我不起作用。我的意图是编辑一个已经创建的元素,以便 patch 为我工作。可以吗?
    • 完美,我确实应该在您更新模型时发现这一点。 put 也可以。
    • 如果我可以再问一个问题,put 和 patch 有什么区别?
    • putpatch 的旧形式,而 patch 是 rails 首选的更新动词,了解两者都很好。 This 是一个很好的解释。我
    【解决方案2】:

    是的,您可以通过检查请求类型或发送标志/关键字来检查要呈现的响应来做到这一点,我会这样做:

    在编辑表单中为请求参数添加hidden_field,例如:

    <%= form_for [@scoreboard, @team], remote: true do |f| %> 
    
         <div class="row team-edit-form">
            <div class="col-xs-4 edit-team-1">Placeholder</div>
    
    
            <div class="col-xs-2 edit-team-2"><%= f.number_field :win, min: 0, max: 9999, class: "form-control", placeholder: "0"  %>
            <%= f.hidden_field :request, 'js' %> </div>
    
    
            <div class="col-xs-2 edit-team-2"><%= f.number_field :loss, min: 0, max: 9999, class: "form-control", placeholder: "0" %></div>
    
            <div class="col-xs-2 edit-team-2"><%= f.number_field :tie, min: 0, max: 9999, class: "form-control", placeholder: "0" %></div>
    
            <div class="col-xs-2 edit-team-3"> <%= f.submit "Done", :data => {:disable_with => "Saving..."}, class: "btn btn-primary" %></div>
         </div>
     <% end %>
    

    在显示页面的名称编辑表单中为请求参数添加hidden_field,例如:

    <%= form_for [@scoreboard, @team] do |f| %>
    
            <div class="col-xs-4"><%= f.text_field :name, required: true, maxlength: 30, class: "team-name-field form-control", placeholder: "Enter name"  %> 
             <%= f.hidden_field :request, 'http' %> </div>
    
            <div class="col-xs-1"> <%= f.submit "Update", :data => {:disable_with => "Saving..."}, class: "btn btn-primary" %></div>
    
    <% end %>
    

    Team#Update 方法如下:

    def update
        @scoreboard = Scoreboard.find(params[:scoreboard_id])
        @team = @scoreboard.teams.find(params[:id])
        if @team.update_attributes(team_params)
             redirect_to scoreboard_teams_path(@scoreboard)  if params[:request] == 'http'
             render ""  if params[:request] == 'js'
        else
             redirect_to scoreboard_teams_path(@scoreboard) if params[:request] == 'http'
             render action: "update_error"  if params[:request] == 'js'
        end
     end 
    

    【讨论】:

      猜你喜欢
      • 2012-06-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多