如何使用nested_form更新另一个对象时创建对象(has_many belongs_to association)

时间:2016-08-18 13:33:08

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

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

Models.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

客户端/ 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'

1 个答案:

答案 0 :(得分:0)

你可以在控制器中执行类似的操作,放在客户端更新块中。

@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