不要使用 gem cocoon 显示字段嵌套属性
Dont display fields nested attributes with using gem cocoon
我有带嵌套属性的模型投票 poll_items:
class Poll < ActiveRecord::Base
ITEMS_COUNT_MAX = 5
attr_accessible :from_date, :question, :results_hidden, :to_date, :owner_id, :poll_items_attributes
belongs_to :owner, polymorphic: true
has_many :poll_items, dependent: :destroy
has_many :poll_votes, through: :poll_items
accepts_nested_attributes_for :poll_items, allow_destroy: true,
reject_if: proc { |attributes| attributes['answer'].blank? }
#validates :owner, :question, :from_date, :to_date, presence: true
#validate :validate_duplicate, on: :create
validate :validate_max_poll_items, on: :update
after_initialize :defaults
...................................................................
模型 pollItem
attr_accessible :answer
attr_readonly :poll_votes_count
belongs_to :poll
has_many :poll_votes, dependent: :destroy
has_many :users, through: :poll_votes
validates :poll, :answer, presence: true
validate :validate_duplicate, on: :create
scope :editable, lambda { |u|
unless u.moderator?
where(:poll.owner.user_id => u.id).where(:created_at.gt Settings.edit_delay.minutes.ago)
end
}
private
def validate_duplicate
errors.add(:base, :duplicate) unless poll.poll_items.where(answer: answer).empty?
end
end
Poll_controller:
class PollsController < ApplicationController
before_filter :authenticate_user!
before_filter :set_poll, only: [:show, :edit, :update, :destroy]
before_filter :find_owner, only: [:new, :create]
def new
@poll = Poll.new
end
def create
@poll = Poll.new params[poll_params]
#@poll.owner = @owner
respond_to do |format|
if @poll.save
format.html { redirect_to [:edit, @poll], notice: 'Опрос был успешно создан.' }
else
format.html { render :new }
end
end
end
def show
end
def edit
@poll.poll_items.build
end
def update
if @poll.editable?(current_user)
if @poll.update_attributes params[:poll]
respond_to do |format|
format.html { redirect_to [:edit, @poll], notice: 'Опрос был успешно обновлен.' }
end
else
respond_to do |format|
format.html { render :edit, alert: @poll.errors }
end
end
end
end
def destroy
@poll.destroy
respond_to do |format|
format.html { redirect_to @owner, notice: 'Опрос был успешно удален.' }
end
end
private
def poll_params
params.require(:poll).permit(:from_date, :question, :results_hidden, :to_date,
:owner_id, poll_items_attributes: [:id, :unswer, :_destroy])
end
protected
def set_poll
@poll = Poll.find(params[:id])
@owner = @poll.owner
end
def find_owner
@owner = case
when params[:post_id]
Post.visible(current_user).find(params[:post_id])
when params[:blog_post_id]
BlogPost.with_privacy(current_user).find(params[:blog_post_id])
end
end
end
我安装了gem cocoon:
接下来我创建视图 new.html.haml:
%h1= title "Новый опрос"
= simple_form_for @poll do |f|
= f.error_messages header_message: nil
= f.input :question, disabled: !@poll.editable?(current_user), input_html: { class: 'input-block-level' }
= f.input :results_hidden, as: :boolean, inline_label: 'Скрыть результаты до окончания опроса', label: false
= f.input :from_date, as: :datetime, input_html: { class: 'poll_date' }
= f.input :to_date, as: :datetime, input_html: { class: 'poll_date' }
.items-index
%h3#poll-items Варианты ответа (не больше пяти)
= f.simple_fields_for :poll_items do |poll|
= render 'poll_items_fields', f: poll
= link_to_add_association 'Добавить еще вариант', f, :poll_items
.form-actions
= f.button :submit, 'Опубликовать опрос', class: 'btn-bg'
%p
Вернуться к посту:
= link_to @owner
poll_items_fields.html.haml:
.poll_row
.poll_item
= f.input :answer, input_html: { class: 'ctrlenter expanding' }, label: false, placeholder: 'Введите вариант ответа'
= link_to_remove_association "удалить", f
我打开新页面来创建新投票,但只有新名称、投票和按钮的字段 "create poll"。没有用于添加 poll_items 的字段。我认为我不渲染表单 poll_items_fields.html.haml。但为什么?怎么修?
如果我没理解错的话,你的 new
方法应该是这样的
def new
@poll = Poll.new
@poll.poll_items.build
end
还有 unswer
而不是 poll_items_attributes
中的 answer
,所以也要修正它。
def poll_params
params.require(:poll).permit(:from_date, :question, :results_hidden, :to_date, :owner_id, poll_items_attributes: [:id, :answer, :_destroy])
end
更新:
您还应该从 Poll
模型中删除 attr_accessible :from_date, :question, :results_hidden, :to_date, :owner_id, :poll_items_attributes
,因为 Rails 4 使用 强参数。
而且 create
方法中的这一行 @poll = Poll.new params[poll_params]
应该如下所示 @poll = Poll.new(poll_params)
我有带嵌套属性的模型投票 poll_items:
class Poll < ActiveRecord::Base
ITEMS_COUNT_MAX = 5
attr_accessible :from_date, :question, :results_hidden, :to_date, :owner_id, :poll_items_attributes
belongs_to :owner, polymorphic: true
has_many :poll_items, dependent: :destroy
has_many :poll_votes, through: :poll_items
accepts_nested_attributes_for :poll_items, allow_destroy: true,
reject_if: proc { |attributes| attributes['answer'].blank? }
#validates :owner, :question, :from_date, :to_date, presence: true
#validate :validate_duplicate, on: :create
validate :validate_max_poll_items, on: :update
after_initialize :defaults
...................................................................
模型 pollItem
attr_accessible :answer
attr_readonly :poll_votes_count
belongs_to :poll
has_many :poll_votes, dependent: :destroy
has_many :users, through: :poll_votes
validates :poll, :answer, presence: true
validate :validate_duplicate, on: :create
scope :editable, lambda { |u|
unless u.moderator?
where(:poll.owner.user_id => u.id).where(:created_at.gt Settings.edit_delay.minutes.ago)
end
}
private
def validate_duplicate
errors.add(:base, :duplicate) unless poll.poll_items.where(answer: answer).empty?
end
end
Poll_controller:
class PollsController < ApplicationController
before_filter :authenticate_user!
before_filter :set_poll, only: [:show, :edit, :update, :destroy]
before_filter :find_owner, only: [:new, :create]
def new
@poll = Poll.new
end
def create
@poll = Poll.new params[poll_params]
#@poll.owner = @owner
respond_to do |format|
if @poll.save
format.html { redirect_to [:edit, @poll], notice: 'Опрос был успешно создан.' }
else
format.html { render :new }
end
end
end
def show
end
def edit
@poll.poll_items.build
end
def update
if @poll.editable?(current_user)
if @poll.update_attributes params[:poll]
respond_to do |format|
format.html { redirect_to [:edit, @poll], notice: 'Опрос был успешно обновлен.' }
end
else
respond_to do |format|
format.html { render :edit, alert: @poll.errors }
end
end
end
end
def destroy
@poll.destroy
respond_to do |format|
format.html { redirect_to @owner, notice: 'Опрос был успешно удален.' }
end
end
private
def poll_params
params.require(:poll).permit(:from_date, :question, :results_hidden, :to_date,
:owner_id, poll_items_attributes: [:id, :unswer, :_destroy])
end
protected
def set_poll
@poll = Poll.find(params[:id])
@owner = @poll.owner
end
def find_owner
@owner = case
when params[:post_id]
Post.visible(current_user).find(params[:post_id])
when params[:blog_post_id]
BlogPost.with_privacy(current_user).find(params[:blog_post_id])
end
end
end
我安装了gem cocoon:
接下来我创建视图 new.html.haml:
%h1= title "Новый опрос"
= simple_form_for @poll do |f|
= f.error_messages header_message: nil
= f.input :question, disabled: !@poll.editable?(current_user), input_html: { class: 'input-block-level' }
= f.input :results_hidden, as: :boolean, inline_label: 'Скрыть результаты до окончания опроса', label: false
= f.input :from_date, as: :datetime, input_html: { class: 'poll_date' }
= f.input :to_date, as: :datetime, input_html: { class: 'poll_date' }
.items-index
%h3#poll-items Варианты ответа (не больше пяти)
= f.simple_fields_for :poll_items do |poll|
= render 'poll_items_fields', f: poll
= link_to_add_association 'Добавить еще вариант', f, :poll_items
.form-actions
= f.button :submit, 'Опубликовать опрос', class: 'btn-bg'
%p
Вернуться к посту:
= link_to @owner
poll_items_fields.html.haml:
.poll_row
.poll_item
= f.input :answer, input_html: { class: 'ctrlenter expanding' }, label: false, placeholder: 'Введите вариант ответа'
= link_to_remove_association "удалить", f
我打开新页面来创建新投票,但只有新名称、投票和按钮的字段 "create poll"。没有用于添加 poll_items 的字段。我认为我不渲染表单 poll_items_fields.html.haml。但为什么?怎么修?
如果我没理解错的话,你的 new
方法应该是这样的
def new
@poll = Poll.new
@poll.poll_items.build
end
还有 unswer
而不是 poll_items_attributes
中的 answer
,所以也要修正它。
def poll_params
params.require(:poll).permit(:from_date, :question, :results_hidden, :to_date, :owner_id, poll_items_attributes: [:id, :answer, :_destroy])
end
更新:
您还应该从 Poll
模型中删除 attr_accessible :from_date, :question, :results_hidden, :to_date, :owner_id, :poll_items_attributes
,因为 Rails 4 使用 强参数。
而且 create
方法中的这一行 @poll = Poll.new params[poll_params]
应该如下所示 @poll = Poll.new(poll_params)