嵌套属性的条件?

时间:2016-10-07 10:24:21

标签: ruby-on-rails ruby

如何创建一个条件,如果dueler是current_user,那么它将列出current_user的挑战,如果dueler是@user那么它会列出@用户的挑战?

duels_controller

def new
  @user = User.find(params[:challenge_daddy])
  @duel = Duel.new
  @duel.duelers << Dueler.new(user_id: current_user.id, user_name: current_user.name, user_last_name: current_user.last_name)
  @duel.duelers << Dueler.new(user_id: @user.id, user_name: @user.name, user_last_name: @user.last_name)
  @current_user_challenges = current_user.challenges.order(:created_at)
  @challenged_user_challenges = @user.challenges.order(:created_at)
  respond_with(@duel)
end

决斗/ _form.html.erb

<%= simple_form_for(@duel) do |f| %>
  <%= f.fields_for :duelers do |dueler| %>
    <%= render 'dueler_fields', :f => dueler %>
  <% end %>
  The loser will <%= f.text_field :consequence %>.
  <%= f.submit %>
<% 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
<%= collection_select(:dueler, :challenge_id, # @challenged_user_challenges or @current_user_challenges
, :id, :full_challenge, include_blank: true) %>

如何创建条件,以便如果:user_id等于current_user,那么@current_user_challenges将显示在collection_select中,如果:user_id相等到@user然后@challenged_user_challenges会显示?

1 个答案:

答案 0 :(得分:1)

您可以添加一些java / coffee脚本来执行此操作,因为这意味着对表单进行实时更改。

将当前用户添加到数据和部分(或两个不同的collection_selects with ids):

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

添加app / assets / javascripts / challengers.coffee

$(document).ready ->
  userSelect = $('#change-challenge-options')
  userSelect.on 'valuesChanged', ->
    currentUserId = $('#current-challenge-options').data('current-user-id')
    if(currentUserId == userSelect.val())
      ... show / hide the correct fields
    else
      ... show / hide the correct fields
    $(window).resize            #Not necessary but makes it look nicer if the lists are long.

不知道这是否是最好的解决方案,但我在项目中做了类似的事情并且工作正常。

编辑: 首先,您需要为视图添加两种情况的collection_select字段,并为它们提供ID:

<%= collection_select(:dueler, :challenge_id, @current_user_challenges, :id, :full_challenge, include_blank: true), id: "current-user-challenges" %>
<%= collection_select(:dueler, :challenge_id, @challenged_user_challenges, :id, :full_challenge, include_blank: true), id: "challenged-user-challenges" %>

然后在脚本中你需要添加:

if(currentUserId == userSelect.val())
   $('#current-user-challenges').show()
   $('#challenged-user-challenges').hide()
else
   $('#challenged-user-challenges').show()
   $('#current-user-challenges').hide()

这将显示/隐藏正确的字段。我不确定如何向collection_selects添加id,但如果我的提议不起作用,只需将它们放在div或其他容器中即可。给这些容器id并以相同的方式显示/隐藏它们。

除此之外,您可能还想添加一些首次访问或正确重新访问表单的脚本。所以完整的代码将是:

#page:load just makes sure the page is fully loaded before running script.
#Usefull if you use turbolinks etc.
$(document).on 'ready page:load' ->
  userSelect = $('#change-challenge-options')
  currentUserId = $('#current-challenge-options').data('current-user-id')
  $(window).on 'page:change', ->
    if(userSelect.val()) #All none zero values are true in js
      if(currentUserId == userSelect.val()) #Show the right field
        $('#current-user-challenges').show()
        $('#challenged-user-challenges').hide()
      else
        $('#challenged-user-challenges').show()
        $('#current-user-challenges').hide()
    else                                    #Hide both fields if no user is chosen.
      $('#challenged-user-challenges').hide()
      $('#current-user-challenges').hide()
    $(window).resize
  userSelect.on 'valuesChanged', ->
    if(currentUserId == userSelect.val())
      $('#current-user-challenges').show()
      $('#challenged-user-challenges').hide()
    else
      $('#challenged-user-challenges').show()
      $('#current-user-challenges').hide()
    $(window).resize

我希望它对你有用!

这里是使用javascript代替coffee和raw html的概念的工作片段:

&#13;
&#13;
var userSelect = $('#change-challenge-options');
var currentUserId = $('#current-user-id').data('user-id');
$('#challenged-user-challenges').hide();
$('#current-user-challenges').hide();
userSelect.on('change', function() {
  if (userSelect.val() == "0"){
     $('#current-user-challenges').hide();
     $('#challenged-user-challenges').hide();
    }
  else if (userSelect.val() == currentUserId) {
    $('#current-user-challenges').show();
    $('#challenged-user-challenges').hide();
  } else {
    $('#challenged-user-challenges').show();
    $('#current-user-challenges').hide();
  }
});
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<!DOCTYPE html>
<form id="new_challenge" role="form" accept-charset="UTF-8">
  <div class="form-group" id="current-user-id" data-user-id = "1">
    <label class="control-label col-sm-2">User:</label>
    <select class="form-control" name="users" id="change-challenge-options">
      <option selected="selected" value="0">Choose user...</option>
      <option value="1">Me</option>
      <option value="2">Other user</option>
    </select>
  </div>
  <label class="control-label col-sm-2">Challenges:</label>
  <div class="form-group">
    <select class="form-control" name="users" id="current-user-challenges">
      <option selected="selected" value="0">Choose challenge...</option>
      <option value="1">My challenge 1</option>
      <option value="2">My challenge 2</option>
    </select>
  </div>
  <div class="form-group">
    <select class="form-control" name="users" id="challenged-user-challenges">
      <option selected="selected" value="0">Choose challenge...</option>
      <option value="1">Other user challenge 1</option>
      <option value="2">Other user challenge 2</option>
      <option value="3">Other user challenge 3</option>
    </select>
  </div>
  </div>
</form>
&#13;
&#13;
&#13;