Понимание сохраняемости переменных rails с помощью jQuery

#jquery #ruby-on-rails #forms #object

#jquery #ruby-on-rails #формы #объект

Вопрос:

Когда я создаю новый объект с помощью контроллера, построенного на каркасах, если я запускаю какой-либо скрипт jquery в свою форму и эти скрипты запускают функцию в моем контроллере, эта функция не знает об объекте, который я только что создал. Почему?

Позвольте мне объяснить:

В моем контроллере я сначала создаю свой объект:

   def new
    @projectmilestone = Projectmilestone.new

    respond_to do |format|
      format.html # new.html.erb
      format.xml  { render :xml => @projectmilestone }
    end
  end
  

На мой взгляд, у меня есть форма с одним вложенным частичным:

 <%= semantic_form_for [:projects,@projectmilestone]  do |form| %>

    <%= form.semantic_errors :state %>
    <%= form.inputs do %>
      <%= form.input :department_id, :as => :select, :collection => Department.all%>
      <div id="stakeholders">
          <%=render :partial => "stakeholders", :locals => {:users => @users }%>
      </div>

    <%  end %>

    <%= form.submit "Submit" %>

<% end %>
  

Часть заинтересованных сторон выглядит следующим образом:

 <%= semantic_form_for [:projects,@projectmilestone], :remote => true  do |form| %>
    <%= form.inputs :partial do %>
      <%= form.input :user_id , :as => :select, :collection => users %>
    <% end %>
<% end %>
  

Когда я изменяю значение department_id, в моем application.js файл:

 $('#projectmilestone_department_id').live('change', function() {
    // make a POST call and replace the content
    var department = $('select#projectmilestone_department_id :selected').val();
    if(department == "") department="0";
    var milestone = $('#form_id').html();
    jQuery.get('/projects/projectmilestones/update_user_select/'   department, function(data){
        $("#stakeholders").html(data);
    })
    return false;
  });
  

Эта функция вызывает функцию update_user_select в моем контроллере:

  def update_user_select
    users=""
    users = User.where(:department_id=>params[:department_id]) unless params[:department_id].blank?
    render :partial => "stakeholders", :locals => {:users => users }
  end
  

Затем пользовательская часть должна перезагрузиться в моей форме, но этого не происходит, потому что @projectmilestone равен нулю.

Почему @projectmilestone не сохраняется, когда я использую этот скрипт jquery, и сохраняется, когда я перехожу к функции create моего каркаса?

Большое спасибо!!!

Ответ №1:

Причина в том, что когда Rails отображает вашу страницу, переменная экземпляра, которую вы устанавливаете в контроллере, является общей для представления и частичных элементов. Это часть стека, на стороне сервера и отправляется клиенту в вашем браузере.

Но когда вы используете Ajax, вы работаете с клиента, и сервер больше не знает о том, что он отправил ранее, если вы не напомните об этом, отправив идентификатор объекта, над которым вы работаете.

Комментарии:

1. Спасибо за ваш ответ. Идентификатор объекта — это не тот, который будет установлен в базе данных, когда я сохраню (вставлю sql) объект, верно? Итак, как я могу отправить этот идентификатор объекта контроллеру и заставить контроллер использовать его в моем методе update_user_select?

2. вы правы, это не идентификатор будущего объекта db. Но чтобы сохранить один объект, вы должны сгенерировать html, совместимый с уже существующим html. Возможно, было бы проще сделать это вручную вместо использования помощников формы. Вы могли бы черпать вдохновение в коде Райана Бейтса. Смотрите github.com/ryanb/nested_form

3. Я взглянул на это, но для меня это слишком сложно… На данный момент, в качестве обходного пути, я добавил @projectmilestone = params[:id].to_i != 0 ? Projectmilestone.find(параметры [:id]) : Projectmilestone. новое в моей функции контроллера. Кажется, что это выполняет свою работу, несмотря на то, что это не очень элегантно… Спасибо!