#ruby-on-rails #database #forms #activerecord
#ruby-on-rails #База данных #формы #activerecord
Вопрос:
У меня есть две модели, Page и PageContent.
class Page < ActiveRecord::Base
has_many :page_contents
end
class PageContent < ActiveRecord::Base
belongs_to :page
end
Страница имеет атрибут:css_design, но я хочу иметь возможность редактировать этот атрибут из моей формы PageContent. Есть идеи?
Я вижу много accepts_nested_attributes и fields_for advice, но они не работают, потому что все они, похоже, предназначены для форм, которые либо являются A. Создание целых новых экземпляров другой модели из формы (например, создание задач из формы проекта), либо B. Обновление связанных записей через родительскую. Я хочу сделать обратное — я хочу обновить родительскую запись через связанные записи.
Любая помощь приветствуется! Заранее большое спасибо!
—Отметить
Обновить
Я добавил следующее в свою модель 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 amp;amp; @css_design
end
И у меня есть как в моих действиях create, так и в update:
@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'
Когда я захожу в create the page_content в первый раз. Я скопировал и вставил этот материал прямо из своих файлов, поэтому, если вы увидите что-нибудь странное, пожалуйста, дайте мне знать!
Комментарии:
1. Черт возьми, я ожидал, что здесь сработает accepts_nested_attributes_for, но ниже есть пара других решений, которые стоит изучить…
Ответ №1:
Обновите свою модель следующим образом:
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 amp;amp; @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. Спасибо, Джереми, когда я пытался запустить это, это работало на существующих страницах (для редактирования), но не при создании нового PageContent. Конкретная ошибка, которую я получаю, такова: NoMethodError в Page_contents#new Любые подсказки, которые укажут мне правильное направление, были бы с благодарностью приняты!
2. Отметьте, я отредактировал свой ответ с помощью кода, который изящно не будет обрабатывать ассоциацию страниц.
3. Спасибо, Джереми, теперь я получаю сообщение об ошибке при отправке формы PageContent: ‘NoMethodError (неопределенный метод
css_design=' for #<Page:0x00000003a80338>): app/models/page_content.rb:13:in
css_design=’ app / controllers /page_contents_controller.rb:56:вnew' app/controllers/page_contents_controller.rb:56:in
создании’4. В моей модели PageContent содержится следующее: определить css_design страницы? страница.css_design: нулевое определение конца css_design= (значение), если страница страница.update_attribute ‘css_design’, значение else @css_design = значение конца end after_create :set_page_css_design_on_create определение set_page_css_design_on_create self.css_design = @css_design если страница amp;amp; @ css_design завершение
Ответ №2:
Если полей не слишком много, вы можете добавить атрибуты к модели 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?(атрибут)) поэтому он не перезаписывает ее значением nil.
(Извините, у меня нет времени протестировать это сразу. Я попробую позже. )