Skip to content

Instantly share code, notes, and snippets.

@jhjguxin
Created September 20, 2012 12:38
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jhjguxin/3755631 to your computer and use it in GitHub Desktop.
Save jhjguxin/3755631 to your computer and use it in GitHub Desktop.
mongoid dynamic_fields demo base on bbtangcms(recommend_other depend on other_column)
<%= simple_form_for(@recommend_recommend_other, :html => {id: "recommend_recommend_other"}) do |f| %>
<%= f.error_notification %>
<div class="form-inputs">
<%= f.input :_id, as: :hidden %>
<%= f.input :recommend_other_type, as: :select, collection: Recommend::OtherColumn.all.map(&:recommend_type) %>
<%# f.input :created_at %>
<%# f.input :updated_at %>
<% dynamic_feilds = @recommend_recommend_other.dynamic_attribute_names %>
<% if dynamic_feilds.present? %>
<% dynamic_feilds.each do |dynamic_feild|%>
<%= f.input dynamic_feild, :label => "#{@recommend_recommend_other.dynamic_attribute_human(dynamic_feild)}" %>
<% end %>
<% end %>
</div>
<div class="form-actions">
<%= f.button :submit, :class => 'btn-primary', :disable_with => 'loading...' %>
<%= link_to t('.cancel', :default => t("helpers.links.cancel")),
recommend_recommend_others_path, :class => 'btn' %>
</div>
<% end %>
# encoding: utf-8
class Recommend::OtherColumn
include Mongoid::Document
#include Mongoid::Timestamps::Created
include Mongoid::Timestamps
field :recommend_type, type: String
#field :other_column_hash, type: Array#[human_name , colmun_name]
field :human_names, type: Array #[human_name1 , human_name2, human_name3]
field :column_names, type: Array #[colmun_name1 , colmun_name2, colmun_name3]
before_validation :set_array
validates_uniqueness_of :recommend_type
def set_array
self.human_names = convert_array(self.human_names)
self.column_names = convert_array(self.column_names)
end
def convert_array(str=nil)
if str.present?
str = str.to_s.split(/,|,|;|;|\ +|\||\r\n/).collect {|t| t if t.present?}.uniq.compact
else
[]
end
end
=begin
def dynamic_attributes
self.attributes.delete_if { |attribute|
self.fields.keys.member? attribute
}
end
=end
end
# encoding: utf-8
class Recommend::RecommendOther
include Mongoid::Document
#include Mongoid::Timestamps::Created
include Mongoid::Timestamps
before_validation :auto_update_feild
field :recommend_other_type, type: String
#dynamic_fields Recommend::OtherColumn.where(:recommend_type => "index_foucus").entries
def dynamic_attributes
#update feild
auto_update_feild
#attr_hash = self.attributes
attr_hash = self.attributes.clone
attr_hash.delete_if { |attribute|
self.fields.keys.member? attribute
}
end
def other_columns
Recommend::OtherColumn.where(:recommend_type => self.recommend_other_type).entries.first
end
def dynamic_attribute_names
dynamic_attributes.keys
end
def dynamic_attribute_human(col = nil)
if col.present? and other_columns.present?
col_index = other_columns.column_names.index(col)
human_name = other_columns.human_names.send("[]",col_index)
if col_index.present? and human_name.present?
human_name
else
col
end
end
end
def new
if self.recommend_other_type.present? and other_columns.present?
columns = other_columns.column_names
if columns.present?
#can not work
#columns.collect{|col| self.send("[]=",col.to_sym,nil) unless self.fields.keys.include? col.to_s}
columns.collect{|col| self.send("[]=",col.to_sym,nil) unless self.respond_to? col.to_s}
end
return self
else
super
end
end
def auto_update_feild
if self.recommend_other_type.present? and other_columns.present?
columns = other_columns.column_names
if columns.present?
columns.collect{|col| self.send("[]=",col.to_sym,nil) unless self.respond_to? col.to_s}
end
return self
end
end
def to_s
"#{self.recommend_other_type}" if self.recommend_other_type.present?
end
end
class Recommend::RecommendOthersController < ApplicationController
load_and_authorize_resource :class =>"Recommend::RecommendOther", :except => :update_field
Model_class = Recommend::RecommendOther.new.class
# GET /recommend/recommend_others
# GET /recommend/recommend_others.json
def index
@recommend_recommend_others = Recommend::RecommendOther.all.desc(:recommend_other_type).entries
breadcrumbs.add I18n.t("helpers.titles.#{current_action}", :model => Model_class.model_name.human), recommend_recommend_others_path
respond_to do |format|
format.html # index.html.erb
format.json { render json: @recommend_recommend_others }
end
end
# GET /recommend/recommend_others/1
# GET /recommend/recommend_others/1.json
def show
@recommend_recommend_other = Recommend::RecommendOther.find(params[:id])
breadcrumbs.add I18n.t("helpers.titles.#{current_action}", :model => Model_class.model_name.human), recommend_recommend_other_path(@recommend_recommend_other)
respond_to do |format|
format.html # show.html.erb
format.json { render json: @recommend_recommend_other }
end
end
# GET /recommend/recommend_others/new
# GET /recommend/recommend_others/new.json
def new
@recommend_recommend_other = Recommend::RecommendOther.new
breadcrumbs.add I18n.t("helpers.titles.#{current_action}", :model => Model_class.model_name.human), new_recommend_recommend_other_path
respond_to do |format|
format.html # new.html.erb
format.json { render json: @recommend_recommend_other }
end
end
# GET /recommend/recommend_others/1/edit
def edit
@recommend_recommend_other = Recommend::RecommendOther.find(params[:id])
breadcrumbs.add I18n.t("helpers.titles.#{current_action}", :model => Model_class.model_name.human), edit_recommend_recommend_other_path(@recommend_recommend_other)
end
# POST /recommend/recommend_others
# POST /recommend/recommend_others.json
def create
@recommend_recommend_other = Recommend::RecommendOther.new(params[:recommend_recommend_other])
respond_to do |format|
if @recommend_recommend_other.save
format.html { redirect_to @recommend_recommend_other, notice: 'Recommend other was successfully created.' }
format.json { render json: @recommend_recommend_other, status: :created, location: @recommend_recommend_other }
else
format.html { render action: "new" }
format.json { render json: @recommend_recommend_other.errors, status: :unprocessable_entity }
end
end
end
def update_field
recommend_other_type = params[:recommend_other_type]
if recommend_other_type.present? and params[:recommend_other_id].present? and Recommend::RecommendOther.find(params[:recommend_other_id])
@recommend_recommend_other = Recommend::RecommendOther.find(params[:recommend_other_id])
end
@recommend_recommend_other ||= Recommend::RecommendOther.new
@recommend_recommend_other.recommend_other_type = recommend_other_type
@recommend_recommend_other.auto_update_feild
end
# PUT /recommend/recommend_others/1
# PUT /recommend/recommend_others/1.json
def update
@recommend_recommend_other = Recommend::RecommendOther.find(params[:id])
respond_to do |format|
if @recommend_recommend_other.update_attributes(params[:recommend_recommend_other])
format.html { redirect_to @recommend_recommend_other, notice: 'Recommend other was successfully updated.' }
format.json { head :no_content }
else
format.html { render action: "edit" }
format.json { render json: @recommend_recommend_other.errors, status: :unprocessable_entity }
end
end
end
# DELETE /recommend/recommend_others/1
# DELETE /recommend/recommend_others/1.json
def destroy
@recommend_recommend_other = Recommend::RecommendOther.find(params[:id])
@recommend_recommend_other.destroy
respond_to do |format|
format.html { redirect_to recommend_recommend_others_url }
format.json { head :no_content }
end
end
end
$(function($) {
$("#recommend_recommend_other_recommend_other_type").live("change",function() {
$.ajax({url: '/recommend/recommend_others/update_field',
data : {
recommend_other_type : this.value,
recommend_other_id : $("#recommend_recommend_other_id").val()
},
dataType: 'script'})
});
});
<%- model_class = Recommend::RecommendOther.new.class -%>
<h1><%=t '.title', :default => t('helpers.titles.show', :model => model_class.model_name.human,
:default => "Show #{model_class.model_name.human}") %></h1>
<%= show_for @recommend_recommend_other do |s| %>
<%= s.attribute :recommend_other_type %>
<% dynamic_feilds = @recommend_recommend_other.dynamic_attribute_names %>
<% if dynamic_feilds.present? %>
<% dynamic_feilds.each do |dynamic_feild|%>
<%= s.label @recommend_recommend_other.dynamic_attribute_human(dynamic_feild) %>
<%= s.value dynamic_feild%>
<% end %>
<% end %>
<%= s.attribute :created_at %>
<%= s.attribute :updated_at %>
<% end %>
<% if can? :update, @recommend_recommend_other %>
<%= link_to t('.edit', :default => t("helpers.links.edit", :model => model_class.model_name.human)), edit_recommend_recommend_other_path(@recommend_recommend_other), :class => 'btn' %> |
<% end %>
<% if can? :read, @recommend_recommend_other %>
<%= link_to t('.back', :default => t("helpers.links.back", :model => model_class.model_name.human)), recommend_recommend_others_path, :class => 'btn' %> |
<% end %>
<% if can? :destroy, @recommend_recommend_other %>
<%= link_to t('.destroy', :default => t("helpers.links.destroy", :model => model_class.model_name.human)), recommend_recommend_other_path(@recommend_recommend_other),
:method => 'delete',
:confirm => t('.confirm',
:default => t("helpers.links.confirm", :default => 'Are you sure?')),
:class => 'btn btn-danger' %>
<% end %>
$("#recommend_recommend_other").replaceWith("<%= escape_javascript(render 'form') %>");
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment