Как мне обновить две модели с одной формой в Ruby on Rails? - PullRequest
0 голосов
/ 11 мая 2011

У меня есть две модели, Page и PageContent.

class Page < ActiveRecord::Base
  has_many :page_contents
end

class PageContent < ActiveRecord::Base
  belongs_to :page
end

Страница имеет атрибут: css_design, но я хочу иметь возможность редактировать этот атрибут из моей формы PageContent. Есть идеи?

Я вижу много acceptpts_nested_attributes и fields_for совета, но они не работают , потому что все они, похоже, для форм, которые либо Создание целых новых экземпляров другой модели из формы (например, создание задач из формы проекта) или Б. Обновление связанных записей через родительский элемент. Я хочу сделать наоборот - я хочу обновить запись родителя через связанные записи.

Любая помощь очень ценится! Большое спасибо заранее!

- Mark


UPDATE


Я добавил следующее в мою модель PageContent:

def css_design
    page ? page.css_design : nil
  end

  def css_design= (val)
    if page
      page.update_attribute 'css_design', val
    else
      @css_design = val
    end
  end

  after_create :set_page_css_design_on_create
  def set_page_css_design_on_create
    self.css_design = @css_design if page && @css_design
  end

И у меня в действиях создания и обновления:

@page_content.update_attributes params[:page_content]

Но я получаю:

NoMethodError (undefined method `css_design=' for #<Page:0x00000003a80338>):
  app/models/page_content.rb:13:in `css_design='
  app/controllers/page_contents_controller.rb:56:in `new'
  app/controllers/page_contents_controller.rb:56:in `create'

Когда я впервые создаю page_content. Я скопировал и вставил этот материал прямо из своих файлов, поэтому, если вы видите что-то странное, пожалуйста, дайте мне знать!

Ответы [ 2 ]

1 голос
/ 11 мая 2011

Обновите вашу модель следующим образом:

class PageContent < ActiveRecord::Base
  belongs_to :page
  def css_design
    page ? page.css_design : nil
  end
  def css_design= (val)
    if page
      page.update_attribute 'css_design', val
    else
      @css_design = val
    end
  end
  after_create :set_page_css_design_on_create
  def set_page_css_design_on_create
    self.css_design = @css_design if page && @css_design
  end
end

Ваша форма теперь может отображать и обновлять значение текущей страницы, даже если она выглядит так, как будто она обрабатывает только PageContent:

<%= form_for @page_content do |f| %>
  ...
  <%= f.text_field :css_design %>
  ...
<% end %>

В вашем контроллере, например ::

def update
  ...
  @page_content.update_attributes params[:page_content]
  ...
end
1 голос
/ 11 мая 2011

Если полей не слишком много, вы можете добавить атрибуты в модель PageContent через attr_accessor. Затем обновите родительский файл after_save. Примерно так:

class PageContent < ActiveRecord::Base
  belongs_to :page

  attr_accessor :css_design

  after_save :update_parent_css

  private

    def update_parent_css
      self.page.update_attribute(:css_design, self.css_design)
    end

end

Затем вы можете поместить поле формы для него, как и любое другое поле PageContent. Если это более одного поля, используйте update_attributes. Кроме того, вы, вероятно, хотите убедиться, что атрибут установлен (используя attribute_present? (Attribute)), чтобы он не перезаписывал его значением nil.

(Извините, у меня нет времени, чтобы проверить это сразу. Я попробую позже.)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...