7

Given the following:

class WebsitesController < ApplicationController
  # POST /websites/save
  # POST /websites/save.json
  def save
    Website.exists?(name: params[:website][:name]) ? update : create
  end

  # POST /websites
  # POST /websites.json
  def create
    @server  = Server.find_or_create_by_name(params[:server_id])
    @website = @server.websites.new(params[:website])

    #etc... @website.save
  end

  # PUT /websites/1
  # PUT /websites/1.json
  def update
    @website = Website.find_by_name(params[:website][:name])

    #etc... @website.update_attributes
  end
end

The client does not have any IDs of these models

The request that gets sent only has the names, but not the ids.

And the following models

class Website < ActiveRecord::Base
  serialize :website_errors

  attr_accessible :plugins_attributes
  has_many :plugins

  accepts_nested_attributes_for :plugins
end

class Plugin < ActiveRecord::Base
  belongs_to :website
end

When I make a POST request to /websites/save.json, the Website gets updated correctly if it exists, but the Plugins that belong to it always get recreated causing duplicate content in the Database. Why does this happen? I redirect to the update action which calls update_attributes so how can it be that it does not update it? I take it that it's because no ID is given with the request.

Can I make the Controller listen to plugin_name instead of plugin_id?

tolgap
  • 9,629
  • 10
  • 51
  • 65
  • Can you post your view and backtrace? – Bigxiang Aug 30 '13 at 02:35
  • when you edit n update using accepts_nested_attribute_for, rails automatically puts hidden id's in the view. Check if hidden id is created properly. – deepthi Aug 30 '13 at 04:03
  • Why do you work with the save action inside your controller? Thats weird.. How does your form looks like? You need to specify the form method inside the views..post or put/patch. I never heard about your problem before. Did you already checked out the railscasts tutorials about nested forms? – Matthias Aug 30 '13 at 05:19
  • @deepika I am not using any forms whatsoever. The data comes from a ruby script. @Mattherick I did check out the railscasts. But I think my problem lies in the fact that the Client ruby script sends the data without IDs, so I would like to make the `name` parameter the actual ID for `Plugins` – tolgap Aug 30 '13 at 07:07

1 Answers1

1

Modify your controller to have this:

def update
  @website = Website.find_by_name(params[:website][:name])
  if @website.update(params)
    redirect_to website_path(@website)
  else
    render :edit
  end
end

Also, if you're using strong_parameters, you'll need this at the bottom of your controller:

params.require(:website).
  permit(
    :name,
    ...,
    plugins_attributes: [
      :name,
      ...,
    ]
  )
end
ryanfelton
  • 68
  • 6