обновление и создание из разных мест в ruby ​​on rail 3 - PullRequest
1 голос
/ 31 января 2011

Могу поспорить, что у других была эта проблема, но я не нашел хорошего решения.

В приложении rails вы можете захотеть делать вещи с одной моделью из разных мест.

Скажите, у вас есть страница Projects, где вы перечисляете все проекты и имеете форму для создания новых.Эта форма также служит формой обновления, если (: id) присутствует.

Допустим, у вас также есть страница показа клиентов, где вы также перечисляете все проекты для конкретного клиента.Здесь вы также хотите редактировать и создавать проекты (для этого клиента)

Когда контроллер получит это, он отправит пользователя на страницу, указанную в блоке response_to.Но иногда вы хотите вернуться на страницу проектов, а иногда - на страницу показа клиентов.

При отправке с ajax.Для страницы проектов вы заполняете ее javascript и ERB, которые не обязательно должны соответствовать странице показа клиентов.

Существует ли элегантный способ справиться с этим без тонны операторов 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 %>

задач / _form

<% if params[:todo_id].nil? %>

<%= form_for([@project,@todo], :url => project_make_todo_path( @project)) do |f| %>



  <% if @todo.errors.any? %>
    <div id="error_explanation">
      <h2><%= pluralize(@todo.errors.count, "error") %> prohibited this todo from being saved:</h2>

      <ul>
      <% @todo.errors.full_messages.each do |msg| %>
        <li><%= msg %></li>
      <% end %>
      </ul>
    </div>
  <% end %>
<%= f.hidden_field :project_id %>
  <div class="field">
    <%= f.label :name %><br />
    <%= f.text_field :name %>
  </div>

  <div class="actions">
    <%= f.submit %>
  </div>
<% end %>
<% else %>
<%= form_for([@project,@todo], :url => project_update_todo_path( @project, @todo)) do |f| %>



  <% if @todo.errors.any? %>
    <div id="error_explanation">
      <h2><%= pluralize(@todo.errors.count, "error") %> prohibited this todo from being saved:</h2>

      <ul>
      <% @todo.errors.full_messages.each do |msg| %>
        <li><%= msg %></li>
      <% end %>
      </ul>
    </div>
  <% end %>
<%= f.hidden_field :project_id %>
  <div class="field">
    <%= f.label :name %><br />
    <%= f.text_field :name %>
  </div>

  <div class="actions">
    <%= f.submit %>
  </div>
<% end %>
<% end %>

частей projects_controller.rb

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

частей маршрутов. 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

1 Ответ

1 голос
/ 01 февраля 2011

Случай использования, когда модель может быть обновлена ​​из разных мест, может сбивать с толку именно по тем причинам, которые вы упомянули: какой контроллер обрабатывает действие обновления;как мне отформатировать форму, чтобы она подходила для всех случаев?Обычно лучшим решением является создание нового представления и нового контроллера для обработки особого случая.Это обеспечивает чистоту вашего кода и не требует использования множества условных выражений.

Например, если вы начинаете с модели Project и ProjectsController, а также с простым редактированием и новой формой, вы в хорошей форме.

Как только вы добавите модель Customer, вы захотите изменить проекты клиента.Лучшее решение - создать отдельную вложенную форму для изменения проектов в редакторе клиента и новых формах.Таким образом, вы не возитесь со своей старой реализацией и просите модель Customer отвечать за обновление своих собственных проектов.

То, что это позволяет вам делать, - это когда вы обновляете проект из проектастраница, вы перенаправлены обратно на страницу проектов, а когда вы обновляете проекты со страницы клиента, вы перенаправлены обратно на страницу клиента.

Убедитесь, что вы сохраняете логику обновления ваших проектов в проекте.Таким образом, вы можете использовать простой вызов @ project.update_attributes независимо от того, в каком контроллере вы находитесь. Вы не хотите иметь бизнес-логику в своих контроллерах или представлениях.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...