Создайте, затем обновите - Rails

У меня есть набор параметров ниже, которые передаются через форму

Parameters: {"utf8"=>"✓", "authenticity_token"=>"pyMkh1eJ7WxYC978XKjdsyGOeGDvi6RTIOSGb9KMqkc=", "link"=>{"category_id"=>"1", "comment"=>"", "url"=>"yahoo.com "}, "type"=>"html", "original_url"=>"http://yahoo.com", "url"=>"http://www.yahoo.com/", "title"=>"Yahoo!", "description"=>"Welcome to Yahoo!, the world's most visited home page. Quickly find what you're searching for, get in touch with friends and stay in-the-know with the latest news and information.", "favicon_url"=>"http://www.yahoo.com/favicon.ico", "provider_url"=>"http://www.yahoo.com", "provider_display"=>"www.yahoo.com", "provider_name"=>"Yahoo", "safe"=>"true", "html"=>"", "thumbnail_url"=>"", "object_type"=>"link", "image_url"=>"", "category_id"=>"1"}

Я хочу создать новую запись «ссылки» в модели ссылок, которая принадлежит модели категорий. Мое действие «создать» в контроллере ссылок выглядит так

  def create
    @category = Category.find_by_id(params[:category_id])
    @link = @category.links.build(params[:link])
    @link.user_id = current_user.id
    respond_to do |format|
        if @link.save
            links_attributes = params.slice(:original_url, :title, :description, :favicon_url, :provider_url, :provider_display, :thumbnail_url, :object_type)
            @link.update_attributes(links_attributes)
        else 

        end
    end     
  end

Если бы я просто сделал @link.save без атрибутов обновления, он сохранил бы только комментарий, URL-адрес и идентификатор категории. Однако вышеприведенное создает 2 записи: один комментарий, URL-адрес и category_id, а другой со всеми данными.

Как я могу убедиться, что это создает только одну запись со всей информацией?

ОБНОВЛЕНИЕ Если бы я мог просто создать запись с тремя параметрами, а затем обновить ее с помощью оставшихся параметров (links_attributes), я бы с этим справился... просто не знаю, как это сделать.

Это вывод, который я получаю при отправке:

Started POST "/categories/1/links" for 127.0.0.1 at 2013-01-11 12:43:44 -0500
Processing by LinksController#create as JS
  Parameters: {"utf8"=>"✓", "authenticity_token"=>"pyMkh1eJ7WxYC978XKjdsyGOeGDvi6RTIOSGb9KMqkc=", "link"=>{"category_id"=>"1", "comment"=>"", "url"=>"bloomberg.com "}, "type"=>"html", "original_url"=>"http://bloomberg.com", "url"=>"http://www.bloomberg.com/", "title"=>"Business, Financial & Economic News, Stock Quotes", "description"=>"Bloomberg is a premier site for business and financial market news. It delivers world economic news, stock futures, stock quotes, & personal finance advice.", "favicon_url"=>"http://www.bloomberg.com/favicon.ico", "provider_url"=>"http://www.bloomberg.com", "provider_display"=>"www.bloomberg.com", "provider_name"=>"Bloomberg", "safe"=>"true", "html"=>"", "thumbnail_url"=>"http://www.bloomberg.com/image/is2KySnyVWmA.jpg", "object_type"=>"link", "image_url"=>"", "category_id"=>"1"}
  User Load (0.1ms)  SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT 1  [["id", 1]]
   (0.1ms)  begin transaction
  SQL (0.4ms)  INSERT INTO "links" ("category_id", "comment", "created_at", "description", "favicon_url", "object_type", "original_url", "points", "profile_link", "provider_display", "provider_url", "thumbnail", "thumbnail_url", "title", "updated_at", "url", "user_id") VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)  [["category_id", "1"], ["comment", ""], ["created_at", Fri, 11 Jan 2013 17:43:

Started POST "/categories/1/links" for 127.0.0.1 at 2013-01-11 12:43:44 -0500
Processing by LinksController#create as JS
  Parameters: {"utf8"=>"✓", "authenticity_token"=>"pyMkh1eJ7WxYC978XKjdsyGOeGDvi6RTIOSGb9KMqkc=", "link"=>{"category_id"=>"1", "comment"=>"", "url"=>""}, "commit"=>"Post", "category_id"=>"1"}
  User Load (0.1ms)  SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT 1  [["id", 1]]
   (0.1ms)  begin transaction
  SQL (0.4ms)  INSE44 UTC +00:00], ["description", "Bloomberg is a premier site for business and financial market news. It delivers world economic news, stock futures, stock quotes, & personal finance advice."], ["favicon_url", "http://www.bloomberg.com/favicon.ico"], ["object_type", "link"], ["original_url", "http://bloomberg.com"], ["points", nil], ["profile_link", nil], ["provider_display", "www.bloomberg.com"], ["provider_url", "http://www.bloomberg.com"], ["thumbnail", nil], ["thumbnail_url", "http://www.bloomberg.com/imRT INTO "links" ("category_id", "comment", "created_at", "description", "favicon_url", "object_type", "original_url", "points", "profile_link", "provider_display", "provider_url", "thumbnail", "thumbnail_url", "title", "updated_at", "url", "user_id") VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)  [["category_id", "1"], ["comment", ""], ["created_at", Fri, 11 Jan 2013 17:43:44 UTC +00:00], ["description", nil], ["favicon_url", nil], ["object_type", nil], ["original_url", nil], ["points", nil], ["profile_link", nil], ["provider_display", nil], ["provider_url", nil], ["thumbnail", nil], ["thumbnail_url", nil], ["title", nil], ["updated_at", Fri, 11 Jan 2013 17:43:44 UTC +00:00], ["url", ""], ["user_id", 1]]
   (1.1ms)  commit transaction
  Rendered links/create.js.erb (0.0ms)
Completed 200 OK in 8ms (Views: 3.9ms | ActiveRecord: 1.6ms)
age/is2KySnyVWmA.jpg"], ["title", "Business, Financial & Economic News, Stock Quotes"], ["updated_at", Fri, 11 Jan 2013 17:43:44 UTC +00:00], ["url", "bloomberg.com "], ["user_id", 1]]
   (2.5ms)  commit transaction
  Rendered links/create.js.erb (0.0ms)

Это моя форма:

<%= form_for([@category, @category.links.build], :remote => true, :class => "form-horizontal") do |f| %>
    <%= f.hidden_field :category_id, :value => params[:id] %>
    Comment: <%= f.text_field :comment %><BR>
    Link: <%= f.text_field :url %>
    <%= f.submit "Post", :class => "btn", :disable_with => '...', :id => "new_link_button" %>
<% end %>

<div class="selector" style="width:350px;margin:-30px 0px 0px 0px;"></div>
<!-- Placeholder that tells Preview where to put the loading icon-->
<div class="loading">
    <img src='http://embedly.github.com/jquery-preview/images/loading-rectangle.gif'>
</div>


<script>


$('#link_url').preview({ key:'60f1dcdf3258476794784148a6eb65e7', // Sign up for a key: http://embed.ly/pricing

      selector : {type:'rich'},
      preview : {
        submit : function(e, data){
          $.ajax({
            dataType: 'script',
            url: this.form.attr('action'),
            type: 'POST',
            data: data
          });
        },
      },
      autoplay : 0,
      maxwidth : 350,
      display : {display : 'rich'}
});

$('#new_link_button').click(function(e) {
    e.preventdevault();
    $('.new_link').submit();
    return false;
});

</script>

Это мои маршруты:

  resources :categories, :only => [:new, :show, :create, :edit, :update] do
    resources :links, :only => [:new, :show, :create, :edit, :update]
    resources :industries, :only => [:new, :show, :create, :edit, :update]
    resources :territories, :only => [:new, :show, :create, :edit, :update]
  end

person user749798    schedule 11.01.2013    source источник
comment
Если ссылки зависят от категорий, возможно, вы сохраняете их в неправильном порядке? Попробуйте сохранить категорию один раз, и я думаю, что все ассоциации сохранятся.   -  person MurifoX    schedule 11.01.2013
comment
Ну, я не создаю новую категорию каждый раз... просто новую ссылку. Ссылки - это подмножество категорий...   -  person user749798    schedule 11.01.2013
comment
Попробуйте прокомментировать строку @link.update_attributes(links_attributes), а затем посмотрите, создает ли она по-прежнему две записи, а затем убедитесь, что никакой другой код, такой как обратные вызовы (after_save, ...), не создает дополнительную запись.   -  person Khaled    schedule 11.01.2013


Ответы (3)


Попробуйте установить их перед сохранением.

def create
  @link = Link.new(params[:link])
  @link.category_id = params[:category_id]
  @link.original_url = params[:original_url]
  @link.title = params[:title]
  @link.description = params[:description]
  @link.user_id = current_user.id
  # etc...
  respond_to do |format|
    if @link.save
      # do things...
    else 
      # do other things...
    end
  end
end
person MurifoX    schedule 11.01.2013
comment
Ну, это странно. Может быть, действие вызывается дважды? - person MurifoX; 11.01.2013
comment
Фу. Не уверена. я только что опубликовал форму и код, вывод и маршруты. Спасибо за помощь. - person user749798; 11.01.2013

Я думаю, что есть проблема с тем, как строится ваша форма. Как видно из опубликованных вами параметров, params[:link] включает только подмножество данных, которые вы пытаетесь сохранить в ссылке:

"link"=>{"category_id"=>"1", "comment"=>"", "url"=>"yahoo.com "}

Все остальное находится на верхнем уровне массива params:

Parameters: {... "original_url"=>"http://yahoo.com", "url"=>"http://www.yahoo.com/", "title"=>"Yahoo!", "description"=>"Welcome to Yahoo!..." ...}

Вы должны посмотреть, как вы используете form_for для построения своей формы, и убедиться, что он правильно используется для дополнительных параметров.

Изменить:

Если вы не можете редактировать форму, вы можете сделать это в своем контроллере:

@link.user_id = current_user.id
links_attributes = params.slice(:original_url, :title, :description, :favicon_url, :provider_url, :provider_display, :thumbnail_url, :object_type)
@link.attributes = links_attributes
respond_to do |format| 
   if @link.save
      ...
person wless1    schedule 11.01.2013
comment
Я не могу это изменить, так как другие параметры добавляются через API. Если бы я мог создать запись, а затем обновить ее с правильными параметрами, это решило бы проблему... - person user749798; 11.01.2013

Прежде всего, вам не нужно вызывать @link.save, а затем @link.update_attributes, потому что @link.update_attributes сохранит @link в вашей БД, если его там еще нет.

Из опубликованных вами журналов кажется, что ваш контроллер получает два почтовых запроса, поэтому он создает два объекта, я думаю, причина в том, что происходят две отправки: одна по отправленной форме, а другая по запросу ajax внутри ваш код $('#link_url').preview(....

person Khaled    schedule 11.01.2013