@challenges = {动态更改用户}。挑战

时间:2016-10-01 06:02:17

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

选择:user_id时,我们如何才能在以下collection_select中显示该用户的挑战?换句话说,我们如何制作

@challenges = @user.challenges.order(:created_at)

例如,

enter image description here

正如您所看到的,列出了所有挑战,即使我更改了user,仍然会列出所有挑战。 javascript永远不会开始列出相应用户的挑战。

模式

  create_table "duelers", force: true do |t|
    t.integer  "user_id"
    t.integer  "challenge_id"
    t.datetime "created_at",     null: false
    t.datetime "updated_at",     null: false
    t.integer  "duel_id",        null: false
    t.boolean  "accept"
    t.string   "user_name"
    t.string   "user_last_name"
    t.string   "challenge_name"
  end

  add_index "duelers", ["duel_id"], name: "index_duelers_on_duel_id", using: :btree

  create_table "duels", force: true do |t|
    t.text     "consequence"
    t.text     "reward"
    t.datetime "created_at",  null: false
    t.datetime "updated_at",  null: false
  end

模型

class Duel < ActiveRecord::Base
  belongs_to :user
  belongs_to :challenge
  has_many :duelers
  accepts_nested_attributes_for :duelers, :reject_if => :all_blank, :allow_destroy => true #correct
end

class Dueler < ActiveRecord::Base
  belongs_to :user
  belongs_to :challenge
  belongs_to :duel
end

路由

get 'duels/user_challenges', :to => 'duels#user_challenges', as: 'user_challenges'

duels_controller

def user_challenges
  @user = User.find(params[:id])
  @challenges = @user.challenges.order(:created_at)
end

def new
  @duel = Duel.new
  @duel.duelers << Dueler.new(user_id: current_user.id, user_name: current_user.name, user_last_name: current_user.last_name)
respond_with(@duel)
end

决斗/ _form

<%= simple_form_for(@duel) do |f| %>
  <%= f.fields_for :duelers do |dueler| %>
    <%= render 'dueler_fields', :f => dueler %>
  <% end %>
  <%= link_to_add_association f, :duelers do %>
    + Dueler
  <% end %>
  The loser(s) will <%= f.text_field :consequence, placeholder: "Enter Consequence" %>
<% end %>

决斗/ _dueler_fields.html.erb

<%= f.select :user_id, User.order(:name).map { |user| [user.full_name, user.id] }, include_blank: true, id: "change-challenge-options" %>

  will

<%= render partial: 'user_challenges', locals: { challenges: Challenge.order(:created_at) } %>

<script> # Upon changing :user_id this javascript never triggers, how to fix it? Not sure if just javascript problem or also controller or ruby
    $( "#change-challenge-options" ).change(function() {
         $.ajax({
            type: "GET",
            url: '<%= user_challenges_path %>',
            data: {name: $('#change-challenge-options').prop('value')}
         });
    });
</script>

决斗/ _user_challenges.html.erb

<div id="dropdown-no-2">
  <%= collection_select(:dueler, :challenge_id, challenges, :id, :full_challenge, include_blank: true) %>
</div>

user_challenges.js.erb

$("#dropdown-no-2").html('<%=j render :partial => "user_challenges", locals: {challenges: @challenges} %>'); 

1 个答案:

答案 0 :(得分:0)

此行是您需要更改的内容:

$( "#change-challenge-options" ).change(function() {

问题是在页面处于就绪状态之前正在运行DOM选择器。如果你运行这样的测试

var nodes = $("#change-challenge-options")
console.log(nodes.length)

您可能会看到节点列表为空。

在静态网站中,您可以将其打包在$(function(){})document.ready(function(){})中,但Rails会因添加turbolinks而稍微复杂一些。

在Rails应用程序中,您有几个选项。

您可以按照建议here将DOM相关代码包装在特殊的侦听器中:

$(document).on('turbolinks:load', function() {
    $( "#change-challenge-options" ).change(function() {
        ...
    }
});

或者您可以遵循jquery.turbolinks gem的建议。 您首先安装gem并将依赖项添加到application.js,然后您可以通过以下方式重构代码:

  1. 绑定document.ready块的 之外的事件。这可能看起来违反直觉;这整个时间我都建议把放在中阻止。
  2. 重构change侦听器以使用以下语法:

    $(document).on('change', '#change-challenge-options', function() {
       ... 
    })
    
  3. 如果所有这些都很困难,您可以从Gemfile,application.js和application.html.erb中删除turbolinks引用。那么典型的document.ready代码就足够了:

    $(function(){
      <all your custom code>
    })