我们有一个应用程序必须使用在.net上运行的外部数据库进行身份验证。有一个单独的Rails应用程序,作为处理身份验证的gem安装。当有人进行身份验证时,他们的信息将存储在会话对象中。应用程序本身就是一种讨论论坛。
当我通过附件控制器创建附件时,所有属性都会正确保存到数据库中。但是,当我在讨论模型中使用nested_attributes_for
执行此操作时,只会传递定义的paperclip属性。 created_by
属性为null。否则,其他一切都是一样的。
为什么没有将此属性添加到数据库?
讨论模式:
class Discussion < ActiveRecord::Base
belongs_to :creator, :class_name => "Person", :foreign_key => "created_by"
belongs_to :updater, :class_name => "Person", :foreign_key => "updated_by"
belongs_to :discussion_group
belongs_to :discussion_category
has_many :discussion_comments, dependent: :destroy
has_many :discussion_attachments, dependent: :destroy
accepts_nested_attributes_for :discussion_attachments, allow_destroy: true
validates :discussion_group_id, on: :create, presence: :true
validates :subject, :body, presence: :true
validates :external_id, on: :create, uniqueness: :true
before_create :add_external_id
validates_associated :creator, :updater, :discussion_group, :discussion_comments, :discussion_attachments
scope :for_discussion_group_ids, ->(ids) {where('discussion_group_id IN (?)', ids)}
scope :for_ext_id, ->(id) {where(external_id: id).first}
....
讨论附件模型:
ALLOWABLE_IMAGES = ["image/gif", "image/jpeg", "image/jpg", "image/png"]
ALLOWABLE_APPLICATIONS = ["application/vnd.oasis.opendocument.text",
"application/vnd.oasis.opendocument.spreadsheet",
"application/vnd.oasis.opendocument.presentation",
"application/vnd.ms-excel",
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
"application/vnd.ms-powerpoint",
"application/vnd.openxmlformats-officedocument.presentationml.presentation",
"application/vnd.openxmlformats-officedocument.wordprocessingml.document",
"application/vnd.ms-word", "application/pdf", "text/plain"]
class DiscussionAttachment < ActiveRecord::Base
belongs_to :discussion
belongs_to :creator, :class_name => "Person", :foreign_key => "created_by"
belongs_to :updater, :class_name => "Person", :foreign_key => "created_by"
has_attached_file :document
validates_attachment :document, :presence => true,
:content_type => { :content_type => ALLOWABLE_APPLICATIONS + ALLOWABLE_IMAGES },
:size => { :in => 0..5.megabytes }
end
讨论控制员:
class DiscussionsController < ApplicationController
before_action :set_discussion, only: [:show, :destroy]
before_action :authorized_for_discussion?, only: [:show]
before_action :authorized_to_start_discussion?, only: [:new, :create]
...
def new
@discussion = Discussion.new
@discussion_group = DiscussionGroup.find(params[:discussion_group_id])
@categories = DiscussionCategory.show.collect{|category| [category.name, category.id]}
3.times {@discussion.discussion_attachments.build(created_by: current_user.PersonID)}
end
def create
@discussion = Discussion.new(discussion_params.merge!({discussion_group_id: params[:discussion_group_id]}))
@discussion.created_by = current_user.PersonID
respond_to do |format|
if @discussion.save
flash[:success] = 'Discussion created successfully.'
format.html { redirect_to discussion_group_discussion_path(@discussion.discussion_group, @discussion), notice: 'Discussion was successfully created.' }
format.json { render action: 'show', status: :created, location: @discussion }
Notify.new_discussion_notification(@discussion).deliver
else
flash[:error] = 'Discussion not created.'
@discussion_group = DiscussionGroup.find(params[:discussion_group_id])
3.times {@discussion.discussion_attachments.build(created_by: current_user.PersonID)}
format.html { render action: 'new' }
format.json { render json: @discussion.errors, status: :unprocessable_entity }
end
end
end
...
private
...
def set_discussion
@discussion = Discussion.find(params[:id])
end
def discussion_params
params.require(:discussion).permit(:discussion_group_id, :discussion_category_id, :subject, :body, :document, discussion_attachments_attributes: [:id, :document])
end
end
讨论观点:
=render partial: 'shared/error_messages', locals: {object: @discussion}
%h1 Create Discussion
%h4 #{@discussion_group.name }
.form-box
=form_for @discussion, url: discussion_group_discussions_path, html: {multipart: true}, method: :post do |f|
=f.hidden_field :discussion_group_id, value: @discussion_group.id
.row
.col-md-8.form-group
=f.label :subject
%span.required *
=f.text_field :subject, class: "form-control", placeholder: 'Enter a subject for your discussion'
.col-md-4.form-group
=f.label :discussion_category, 'Discussion Category'
=f.select :discussion_category_id, DiscussionCategory.show.collect{|category| [category.name, category.id]}, {prompt: true}, {class: 'dropselection form-control'}
.row
.col-md-8.form-group
=f.label :body, "Body"
%span.required *
=f.text_area :body, class: "form-control", rows: 10
.col-md-4.form-group
%label Upload Files
= f.fields_for :discussion_attachments, :html => {class: "form-control"} do |builder|
= builder.file_field :document
%br
.form-group.row
.col-md-12
=f.submit 'Create', class: "btn btn-default"
= link_to 'Cancel', discussion_group_path(@discussion_group), class: 'btn btn-default'
.row
.col-md-12
%small
%span.required *
Denotes required fields
%br
感谢您提供任何帮助。
答案 0 :(得分:0)
如果有人遇到这样的问题。查看rails日志并找出params hash的样子。我遇到的问题是由于构建了多个附件字段,所以:discussion_attachments_attributes指向一个哈希,其键值是附件数组的索引。就我而言,有3个领域。
所以,我在讨论控制器中创建了一个私有方法:
def set_attachments_created_by
attrs = params[:discussion][:discussion_attachments_attributes]
attrs['0'][:created_by] = current_user.PersonID if attrs['0'].present?
attrs['1'][:created_by] = current_user.PersonID if attrs['1'].present?
attrs['2'][:created_by] = current_user.PersonID if attrs['2'].present?
end
然后在创建中,我在创建讨论之前调用该方法:
def create
set_attachments_created_by if params[:discussion][:discussion_attachments_attributes].present?
@discussion = Discussion.new(discussion_params)
@discussion.created_by = current_user.PersonID
....
这可能是一种更优雅的方法,但它可以用于此目的,并允许nested_attribute传递给DiscussionAttachments模型。只需记住在强参数声明中添加:created_by。