【问题标题】:Allowing users to volunteer for a task via ajax允许用户通过 ajax 自愿完成一项任务
【发布时间】:2015-07-06 17:53:49
【问题描述】:

我的应用设置为用户拥有一项任务,其他用户可以自愿完成这些任务。我的模型是这样设置的:

用户

class User < ActiveRecord::Base
  has_many :participations, foreign_key: :participant_id
  has_many :owned_tasks, class_name: "Task", foreign_key: :owner_id
end

参与(加入表)

class Participation < ActiveRecord::Base
  enum status: [:interested, :selected]

  belongs_to :task
  belongs_to :participant, class_name: "User"
end

任务

class Task < ActiveRecord::Base
  enum status: [:open, :in_progress, :complete]

  has_many :participations
  has_many :participants, through: :participations, source: :participant
  # Dynamically generates relations such as 'selected_participants'
  Participation.statuses.keys.each do |status|
    has_many "#{status}_participants".to_sym,
    -> { where(participations: { status: status.to_sym }) },
    through: :participations,
    source: :participant
  end

  belongs_to :owner, class_name: "User"
end

我想做的只是让用户在特定任务的显示视图中单击一个按钮以自愿参与该任务。

我可以在 Rails 控制台中轻松完成此操作:

user = User.first
task = Task.first
user.owned_tasks << task

user_2 = User.find(2)
task.participants << user_2

我遇到困难的地方是试图弄清楚如何设置必要的控制器代码以使其正常工作。我也不确定如何/在哪里创建检查用户是否已经参与任务is_participating? 的条件。它是进入连接模式Participation 还是Task 表?

我想我对视图应该是什么样子有一个模糊的概念:

任务 - 显示视图

<% unless current_user == @task.owner %>
  <div class="volunteer-form">
    <% if current_user.is_participating? %>
        <%= render 'cancel' %>
    <% else %>
        <%= render 'volunteer' %>
    <% end %>
 </div>
<% end %>

_volunteer.html.erb:

 <%= form_for(current_user.participations.build(participant_id: current_user), remote: true) do |f| %>
    <div><%= f.hidden_field :participant_id %></div>
    <%= f.submit "Volunteer" %>
 <% end %>

_cancel.html.erb:

<%= form_for(current_user.participations.find_by(participant_id: current_user), html: { method: :delete }, remote: true) do |f| %>
   <%= f.submit "Cancel" %>
<% end %>

JS

// create.js.erb
$(".volunteer-form").html("<%= escape_javascript(render('tasks/volunteer')) %>");

// destroy.js.erb
$(".volunteer-form").html("<%= escape_javascript(render('tasks/cancel')) %>");

【问题讨论】:

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


    【解决方案1】:

    在您看来,is_participating? 似乎属于 User 模型,它可能应该是这样的:

    def is_participating?(task_id)
      participations.where(task_id: task_id).exists?
    end
    

    至于控制器代码,您可能需要以下内容:

    class ParticipationsController
      # Note I assume you have access to current_user here
    
      def create        
        participation = current_user.participations.create(participation_params)
        respond_to do |format|
          format.js
        end
      end
    
      def destroy
        participation = current_user.participations.find(params[:id])
        participation.destroy
    
        respond_to do |format|
          format.js
        end
      end 
    
    
      protected 
    
      def participation_params
        params.require(:participation).permit :task_id
      end
    end
    

    _volunteer.html.erb 上(请注意,您现在必须将 task 传递到部分):

    <%= form_for(current_user.participations.build, remote: true) do |f| %>
        <%= f.hidden_field :task_id, value: task.id %>
        <%= f.submit "Volunteer" %>
    <% end %>
    

    【讨论】:

    • 在任务的显示视图中出现错误:undefined local variable or method 'task'
    • 这可能是因为你没有将它传递给部分,你的显示视图应该看起来像这样:gist.github.com/manmartinez/ca4ff5f3061eb3a271da
    • 我收到错误:undefined method 'merge' for 1:Fixnum 当我将它作为我的部分参数传递时:&lt;%= render 'volunteer', :task =&gt; @task %&gt;
    • 哦问题是 _volunteer.html.erb 将 hidden_​​field 更改为:&lt;%= f.hidden_field :task_id, value: task.id %&gt;
    • 您对volunteer.html.erb 的更新答案是否有所改变?
    猜你喜欢
    • 1970-01-01
    • 2018-10-08
    • 1970-01-01
    • 2012-02-28
    • 2013-01-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多