Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how do I do a find by id if it exists, otherwise do a find_or_initialize_by_columname(params[:somevalue])

I am trying to allow folks to update records directly if they know the id or to put in name/address type of information and it will find the right record or create a new one if it doesn't exist.

@donor = Donor.find_or_initialize_by_company_and_prefix1_and_first_name1_and_last_name1_and_address1(params[:donor])

The above works just fine as long as the entered record contains all the necessary columns (which it will if I am reading this information in via a csv file.)

But now I would like to offer the option of ONLY including an ID and using that if it does exist in the database. If it doesn't, I would run the above statement to find by those columns or create a new record.

My controller is as follows:

      def create
        # need to find donor by id if given, else use find_or_create_by_blahblahblah

        @donor = Donor.find_or_initialize_by_company_and_prefix1_and_first_name1_and_last_name1_and_address1(params[:donor])


        if @donor.new_record?   
          @donor.save
          respond_to do |format|
            if @donor.save
              format.html { redirect_to @donor, notice: 'Donor was successfully created.' }
              format.json { render json: @donor, status: :created, location: @donor }
            else
              format.html { render action: "new" }
              format.json { render json: @donor.errors, status: :unprocessable_entity }
            end
          end    
        else
          respond_to do |format|
            if @donor.save
              format.html { redirect_to @donor, notice: 'Donor already exists.  Please edit donor if needed.'}
              format.json { render json: @donor, status: :created, location: @donor }
            else
              format.html { render action: "new" }
              format.json { render json: @donor.errors, status: :unprocessable_entity }
            end
          end 
        end   

      end

I am having trouble finding what to do if an ID is supplied to check it.

I tried something like:

@donor = Donor.find_by_id(params[:donor])
if !@donor
   @donor = Donor.find_or_initialize_by_all_those_columns(params[:donor])
end

but this gives me an error if I put data in, say for example, the company field instead of only the ID field.

I am sure there is a slick way to do this that I just haven't seen yet. Any help on it would be appreciated.

like image 873
Aaron Thomas Avatar asked Dec 31 '25 00:12

Aaron Thomas


1 Answers

Try this:

unless @donor = Donor.find_by_id(params[:donor][:id]) // returns `nil` if record not found
    @donor = Donor.find_or_initialize_by_all_those_columns(params[:donor])
end

@donor.new_record? ...

The first line looks for a record with the ID passed in. If it returns a record, then @donor is set to that record and the block is not run. If not, then it will return nil (using find_by_id() instead of find() is important for this reason, because find() raises an error if no record is found), and the block will be run, setting @donor to a record (new or not) with the params.

Hopefully this answers your question.

like image 58
bricker Avatar answered Jan 02 '26 14:01

bricker