【问题标题】:How to create an object when update another with nested_form (has_many belongs_to association)使用nested_form(has_many belongs_to 关联)更新另一个对象时如何创建一个对象
【发布时间】:2023-03-25 05:19:01
【问题描述】:

我有两个模型,Clients 和 Calls,有一个 has_many - belongs_to 关联。我想在每次更新客户端时创建一个新呼叫。使用nested_form,我能够创建它,但它生成的是一个没有参数的空对象。

模型.rb

class Call < ActiveRecord::Base

    belongs_to :client
    has_and_belongs_to_many :interests

end


class Client < ActiveRecord::Base

    has_many :calls, :dependent => :destroy
    belongs_to :user
    has_and_belongs_to_many :interests
    accepts_nested_attributes_for :calls

end

calls_controller.rb

class Admin::CallsController < ApplicationController
  before_action :set_call, only: [:show, :edit, :update, :destroy]
  before_action :authenticate_user!
  layout 'admin'


  # GET /calls
  def index
    @calls = Call.order(created_at: :desc)

  end

  # GET /calls/1
  def show
    @calls = Call.order(created_at: :desc)
  end

  # GET /calls/new
  def new
    # @call = Call.new
  end

  # GET /calls/1/edit
  def edit
  end

  # POST /calls
  def create

    @client = Client.find(params[:client_id])
    @call = @client.calls.create(call_params)


    if @call.save
      redirect_to [:admin, @client], notice: 'Atendimento criado  com sucesso.'
      @call.create_activity :create, owner: current_user

    else
      render :new
    end
  end

  # PATCH/PUT /calls/1
  def update
    # if @call.update(call_params)
    #   redirect_to @call, notice: 'Artigo editado com sucesso.'

    # else
    #   render :edit
    # end
  end

  # DELETE /calls/1
  def destroy
    @client = Client.find params[:client_id]
    @call = @client.calls.find params[:id]
    @call.destroy
    redirect_to (:back), notice: 'Atendimento excluído.'
  end

  private
    # Use callbacks to share common setup or constraints between actions.
    def set_call
      @call = Call.find(params[:id])
    end


    # Only allow a trusted parameter "white list" through.
    def call_params
      params.require(:call).permit(:resume, :calltype, :client_id, interest_ids:[])
    end
end

clients_controller.rb

class Admin::ClientsController < ApplicationController
  before_action :set_client, only: [:show, :edit, :update, :destroy]
  before_action :authenticate_user!

  layout 'admin'


    # Clients.paginate(:page => params[:page], :per_page => 30)
  # GET /clients
  # GET /clients.json
  def index

    @user = current_user
    @calls = Call.order(created_at: :desc)



    if @user.admin?
      @clients = Client.order(created_at: :desc).paginate(:page => params[:page], :per_page => 20)

      @condition = 'ADMINISTRADOR'
      @clients_count = Client.count
    else
      @clients = @user.clients.order(updated_at: :desc).paginate(:page => params[:page], :per_page => 20)
      @condition = 'CORRETOR'
      @clients_count = @user.clients.count
    end
  end



  # GET /clients/1
  # GET /clients/1.json
  def show
    @client = Client.find(params[:id])
    # @calls = Call.order(created_at: :desc)
    @user = current_user

  #.....
  end
  # GET /clients/new
  def new
    @client = Client.new
  end

  # GET /clients/1/edit
  def edit
  end

  # POST /clients
  # POST /clients.json
  def create
    @client = Client.new(client_params)

      if @client.save
        redirect_to [:admin, @client], notice: 'Obrigado pelo Cadastro, entraremos em contato.'
        ClientMailer.new_lead(@client).deliver!

      else
        render new_admin_client_path, notice: 'OOPS! Há problemas no seu formulário, verifique por favor.'
      end

  end

  # PATCH/PUT /clients/1
  # PATCH/PUT /clients/1.json
  def update

    if @client.update(client_params)
      @client.calls.create(@client[:client_id])
      redirect_to admin_clients_path(current_user), notice: 'Cliente atribuído ao corretor '
      # ClientMailer.client_user_set(@client).deliver_now
    else
      render :edit
    end

  end

  # DELETE /clients/1
  # DELETE /clients/1.json
  def destroy
    @client.destroy

    redirect_to admin_clients_url, notice: 'Cliente deletado'

  end

  private
    # Use callbacks to share common setup or constraints between actions.
    def set_client
      @client = Client.find(params[:id])
    end

    # Never trust parameters from the scary internet, only allow the white list through.
    def client_params
      params.require(:client).permit(:name, :telephone, :email, :message, :user_id, :origin, :rg, :cpf, :street, :number, :birthday, :attended, interest_ids:[])
    end


end

clients/edit.slim

  = simple_form_for ([:admin, @client]) do |f|
    h4 = f.error_notification
    .row
      -if current_user.admin?
        .input-field
          = f.collection_select :user_id, User.all, :id, :name, { prompt: "Selecione o corretor..." }

      h3.title Interesses do cliente
      .input-field
        = f.collection_check_boxes :interest_ids, Interest.all, :id, :name do |b| 
          .col.s6.m3.collection-check-box
            = b.check_box
            = b.label 

    .row
      = f.simple_fields_for ([:admin, :client, Call.new]) do |c| 
        .input-field#inline

          = c.input :calltype, collection: ['E-mail', 'Telefone', "WhatsApp"], as: :radio_buttons, label: ""
        .input-field
          = c.input :resume, label: 'Resumo do atendimento'



    .row
      = f.hidden_field :attended, value: true
      .input-field.center
        = f.button :submit, 'Salvar', class: 'btn-large'

【问题讨论】:

    标签: ruby-on-rails ruby ruby-on-rails-4 simple-form nested-forms


    【解决方案1】:

    你能不能在控制器中做这样的事情,放在客户端更新块内。

    @call = Call.new
    @call.calltype = somevalue
    @call.resume = someothervalue
    @call.client_id = valueofclientid
    @call.save
    

    看起来值是 resume、calltype、client_id、interest_ids?您是否可以访问您想要为那里的人提供的值?

    我会在下面将此方法称为 make_new_call 之类的方法,然后直接调用它,但这取决于您。

     def make_new_call
     // put the Call.new -> call.save code in here
     end
    

    然后在那个方法中

       if @client.update(client_params)
           make_new_call
           redirect_to admin_clients_path(current_user), notice: 'Cliente atribuído ao corretor '
           # ClientMailer.client_user_set(@client).deliver_now
         else
           render :edit
         end
    

    【讨论】:

    • 仍然无法访问 clients_controller 中的 call_params ..... 正在保存新呼叫,没有 :resume 和 :calltype !!!
    • 什么设置 calltype 和 resume 数据?它们是基于客户,还是其他一些价值?您是否可以在更新客户端的流程中的任何地方访问该数据?或者您可以在创建记录时在控制器中设置它吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-02-14
    • 1970-01-01
    • 2012-03-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多