【问题标题】:Rails: Remote form in popup window not calling controller actionRails:弹出窗口中的远程表单不调用控制器操作
【发布时间】:2015-09-05 16:54:43
【问题描述】:

我正在编写一个时间跟踪应用程序。我有一个具有time_logged 属性的Project 模型。

我正在使用远程表单(在弹出窗口中呈现)来记录用户的时间。 jQuery 事件处理程序在提交时将跟踪的时间(以秒为单位)分配给表单中的隐藏字段。所有的 JS 都被正确执行。

控制器应该调用一个方法,该方法记录针对表单中选择的项目跟踪的时间,但项目永远不会更新。我在想要么表单没有正确调用控制器动作,要么我编写控制器的方式有问题。

但我不知道是什么。我将在下面包含相关代码 sn-ps。

projects_controller.rb

respond_to :html, :js

  def track
    @project = Project.new 
  end 

  def log_time
    @project = Project.find(params[:project][:id])
    @project.increment_time_logged(project_log_time_params.to_i)
  end

  private 

    def project_params
      params.require(:project).permit(:id, :name, :fee, :client_id)
    end

    def project_log_time_params
      params.require(:project).permit(:time_logged)
    end 

project.rb

  def increment_time_logged(number_of_seconds)
    self.time_logged += number_of_seconds
  end 

routes.rb

  match '/projects/track-time', to: 'projects#track', via: 'get'
  match '/projects/log-time', to: 'projects#log_time', via: 'put'

_track_time_form.html.erb

<%= javascript_include_tag "track.js.erb" %>
<div id="countdown-timer"></div>
<div id="playback-button">&#9658;</div>
<div id="track-time-form">
    <%= form_for @project, :url => "/projects/log-time", remote: true do |p| %>
        <ul>
            <li><%= p.label :project, "Project:"%><br>
            <%= p.collection_select(:id, current_user.projects, :id, :name) %></li>

            <%= p.hidden_field :time_logged, :value => 0 %> <!-- value set by script in log_time.js.erb -->

            <li><%= p.submit "Log time", id: "log-time-button" %></li>
        </ul>
    <% end %>
</div> 

track.js.erb

//initialise form 
timeTrackingForm = window.open("", "", "height=700,width=500");
$(timeTrackingForm.document.body).html("<%= j render( :partial => 'track_time_form' ) %>");

//assign variables 
var timer = $("#countdown-timer", $(timeTrackingForm.document));
var playbackControls = $("#playback-button", $(timeTrackingForm.document));
var form = $("#track-time-form", $(timeTrackingForm.document));
var actual_form = $("#new_project", $(timeTrackingForm.document)); 
var formUl = $("#track-time-form ul", $(timeTrackingForm.document));
var formLi = $("#track-time-form li", $(timeTrackingForm.document));
var logTimeButton = $("#log-time-button", $(timeTrackingForm.document));
var hidden = $("input:hidden", $(timeTrackingForm.document));
var timerPaused;

//initialise timer 
$(timeTrackingForm.document).ready(function(){
    initialiseTimer();
    style();
    $(playbackControls).click(function() {
        playOrPause();
    });
    $(actual_form).submit(function(){ 
        $(timer).timer('pause');
        timerPaused = true;
        var secondsTracked = $(timer).data('seconds');
        $(hidden).val(secondsTracked);
        resetTimerDisplay();
    }); 
});

function initialiseTimer() {
    $(timer).timer({
        format: '%H:%M:%S'
    });
    $(timer).timer('pause');
    timerPaused = true;
}

function resetTimerDisplay() {
    $(timer).timer('reset');
}

function style() {
    $(timer).css({'color':'black','font-size':'50px', 'margin':'auto', 'width':'180px'});
    $(playbackControls).css({'color':'#290052', 'font-size':'50px', 'margin':'auto', 'width':'55px'});
    $(form).css({'width':'300px','margin':'auto'});
    $(formUl).css({'list-style-type':'none'});
    $(formLi).css({'margin':'0 0 25px 0','font-sizeL':'18px','font-family':'Arial'});
    $(logTimeButton).css({'width':'180px','font-size':'18px','background-color':'green','color':'white','margin-top':'15px'});
}

function playOrPause() {
    if (timerPaused == true) {
        $(timer).timer('resume');
        timerPaused = false;
    }
    else {
        $(timer).timer('pause')
        timerPaused = true;
    }
}

【问题讨论】:

  • 你能把登录表单提交中生成的params贴出来吗?我怀疑这条线 @project.increment_time_logged(project_log_time_params.to_i) 是错误的。
  • @Pavan 没有任何生成。我认为这是正常的,因为请求是通过 AJAX 发送的?
  • @Pavan 看起来控制器操作log_time 根本没有被调用。我在方法中添加了puts "log_time has been called",但这根本没有打印在服务器日志中。有什么想法吗?

标签: javascript jquery ruby-on-rails ajax put


【解决方案1】:

您的模型似乎有问题。目前您只是更改属性,而不是将记录保存到数据库。

改变这个

 def increment_time_logged(number_of_seconds)
    self.time_logged += number_of_seconds
  end 

对此:

 def increment_time_logged(number_of_seconds)
    self.time_logged += number_of_seconds
    self.save
 end 

或者,如果您想跳过活动记录验证,请使用:

 def increment_time_logged(number_of_seconds)
    time = self.time_logged += number_of_seconds
    self.update_attribute(:time_logged, time)
 end 

【讨论】:

  • 这绝对是一个促成因素,所以谢谢!看起来问题是 log_time 根本没有被调用(参见上面的 cmets)。有什么想法吗?
  • 在你的控制器中试试这个。如果更新特定属性,则不需要强参数:@project.increment_time_logged(params[:time_logged].to_i)
  • 不会是@project.increment_time_logged(params[:project][:time_logged].to_i) 吗?无论哪种方式,我都尝试了两个版本,但没有这样的运气:(我认为问题是根本没有调用控制器操作。你知道这是为什么吗?
  • 很难说,可能会把你的表单改成 (并尝试使用 chrome 的 rails 面板来调试您的控制器 github.com/dejan/rails_panel
  • 这种变化没有那么幸运。谢谢,我去看看。 :-)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-09-29
  • 1970-01-01
  • 1970-01-01
  • 2011-07-07
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多