首页 > 解决方案 > 通过关系处理时Rails更新属性

问题描述

我正在尝试更新显示页面上的属性,将其保留在显示页面中,该属性通过不同的表连接。例如:经理登录到管理站点并查看多个资源,单击一个并可以查看有权访问该资源的所有用户(已批准或待处理)。他们目前可以删除用户的访问权限。我正在尝试做的是允许经理将请求的状态从待处理更改为已批准。

所以对于我的模型,我有以下内容:

class TrainingResource
  has_many :user_training_resources, dependent: :destroy
end

class UserTrainingResource
  belongs_to :user
  belongs_to :training_resource
 enum status: [:pending, :confirmed, :rejected]

end

class Users
  has_many :user_training_resources, dependent: :destroy
  has_many :training_resources, through: :user_training_resources
end

培训资源控制器

class Admin::TrainingResourcesController < Admin::ApplicationController
  belongs_to_app :training_resources
  add_breadcrumb 'Training Resources', :admin_training_resources_path
  before_action :load_training_resource, only: [:show, :edit, :update, :destroy]
  respond_to :html, :json

  def index
    @training_resources = TrainingResource.paginate(page: params[:page])
    @training_resources = @training_resources.search(params[:search]) if params[:search]
    respond_with(@training_resources)
  end

  def show
    respond_with @training_resource
  end

  def new
    @training_resource = TrainingResource.new
    respond_with(@training_resource)
  end

  def create
    @training_resource = TrainingResource.new(training_resource_params)
    flash[:notice] = 'TrainingResource created successfully' if @training_resource.save
    respond_with @training_resource, location: admin_training_resources_path
  end

  def edit
    respond_with(@training_resource)
  end

  def update
    flash[:notice] = 'TrainingResource updated successfully' if @training_resource.update(training_resource_params)
    respond_with @training_resource, location: admin_training_resources_path
  end

  def destroy
    flash[:notice] = 'TrainingResource deleted successfully' if @training_resource.destroy
    respond_with @training_resource, location: admin_training_resources_path
  end

  private

  def load_training_resource
    @training_resource = TrainingResource.find_by!(id: params[:id])
  end

  def training_resource_params
    params.require(:training_resource).permit(:name, :description, :total_subscriptions, :url)
  end
end

UserTrainingResourcesController,指向 TrainingResourcesController

class Admin::UserTrainingResourcesController < Admin::ApplicationController
  belongs_to_app :training_resources
  add_breadcrumb 'Training Resources', :admin_training_resources_path
  before_action :load_training_resource
  respond_to :html, :json

  def edit
    respond_with @user_training_resource
  end

  def update 
    flash[:notice] = 'UserTrainingResource updated successfully' if @user_training_resource.update(user_training_resource_params)
    respond_with @user_training_resource, location: admin_training_resources_path
  end

  def destroy
    flash[:notice] = 'UserTrainingResource deleted successfully' if @user_training_resource.destroy
    respond_with @user_training_resource, location: admin_training_resources_path
  end

  private

  def load_training_resource
    @user_training_resource = UserTrainingResource.find_by!(id: params[:id])
  end

  def user_training_resource_params
    params.require(:user_training_resources).permit(
  :training_resources_id, :status).merge(user_id: current_user_id)
  end

end

培训资源展示

  <tbody>
    <% @training_resource.users.each do |training| %>
      <tr>
        <td><%= training.full_name %></td>
        <% utr = training.user_training_resources.where(training_resource: @training_resource).first %>
        <td><%= utr.status.capitalize %>
          <%= form_tag '/user_training_resource/edit', :method => :get do %>
            <%= select_tag( :user_training_resources_id, options_for_select(['pending', 'confirmed', 'rejected']))%>
            <%= submit_tag 'Edit Status', class: 'btn btn-default btn-sm' %>
        <% end %>

        <%= tb_form_for [:admin, @training_resource], :remote => true, :data => {:errors => :inline, :success => admin_user_training_resources_path} do |f| %>
          <%= tb_form_errors(f.object, :base) %>
          <%= f.tb_select :name, options_for_select(holder, :status) %>
          <%= f.tb_save_buttons('User Training Resource', admin_user_training_resources_path) %>
        <% end %>
        </td>
        <td class="table-actions">
          <%= link_to 'Edit', edit_admin_user_training_resource_path(training), :class => 'btn btn-default btn-sm' %>
          <%= link_to 'Delete', admin_user_training_resource_path(training), :method => :delete, :data => {:confirm => 'Are you sure you want to delete this?'}, :class => 'btn btn-danger btn-sm'  %>
        </td>
      </tr>
    <% end %>
  </tbody>

用户培训资源助手,Holder 方法

  def holder
    TrainingResource.all.each(&:id)
  end

我最终会删除指向 Edit 的链接,因为它会将用户推送到 UserTrainingResource 编辑页面,并且我想将其保留在当前页面上。带有 select_tag 的顶部表单实际上并未在当前状态下读取,然后 submit_tag 正在重定向页面。

我最近的尝试是底部的form_for。这是在拉入 TrainingResource 而不是 UserTrainingResource 数据。当我将 tb_select 更改为 :status, options_for_select(holder, :status) 时,我最终得到了未定义的方法“status”。看起来它只针对 TrainingResource。我也试过:

在这里认为它会拉入默认状态,然后允许更改选项。'status'的未定义方法仍然存在问题,即使那样保存也存在问题。

我也试过:

在这种情况下,我最终得到了未定义的方法“map”。我试图通过在@training_resource 和@user_training_resource 上尝试复数来确定这一点,但结果是表单中的第一个参数不能包含 nil 或为空。

编辑:

在 UserTrainingResourcesController 中尝试过:

def set_to_confirmed
 @user_training_resource = UserTrainingResource.find(params[:user_training_resource])
end

然后在节目中

              <%= link_to 'Confirmed', {:controller => 'user_training_resources', :action => 'set_to_confirmed', :status => @training_resource.user_training_resource }, :class => 'btn btn-default btn-sm'%>

尽管单击我得到的链接时页面加载没有错误:

Requested URL: https://localhost:3000/admin/set_to_confirmed?status=%23%3CUserTrainingResource%3A%3AActiveRecord_Associations_CollectionProxy%3A0x00007f93ee8b0f90%3E

使用以下内容的最新尝试:

        <% @training_resource.spud_users.each do |training| %>
      <tr>
        <td><%= training.full_name %></td>
        <% utr = training.user_training_resources.where(training_resource: @training_resource).first %>
        <td>
             <%= tb_form_for [:admin, @training_resource], :remote => true, :data => {:errors => :inline, :success => admin_training_resources_path} do |f| %>
               <%= f.select(:user_training_resource_id, options_for_select(['pending', 'confirmed', 'rejected']), :selected => utr.status)%>
               <%= f.tb_save_buttons('', admin_training_resources_path) %>
             <% end %>
        </td>

这将只显示选项,这很好,但我需要它默认为数据库中的当前内容并且保存不粘。

标签: ruby-on-rails

解决方案


如果我明白了,您需要更新连接表以UserTrainingResource更改状态列。

我可能会在中创建三个动作Admin::UserTrainingResourcesController

def set_to_pending
end

def set_to_confirmed
end

def set_to_rejected
end

然后我会在表中的每一行添加三个链接,以TrainingResource#Show传递必要的参数来完成操作,就像这篇文章中解释的那样:pass parameter by link_to ruby​​ on rails


推荐阅读