RubyOnRails3中的单一模型不同视图和CRUD功能

时间:2013-05-24 14:58:46

标签: ruby-on-rails ruby ruby-on-rails-3

作为Ruby on rails的新手,我偶然发现了我的应用程序的一部分。我阅读了RoR框架的基础知识,并了解了rails MVC的“约定优于配置”功能。我有两个表,一个是 apps_events ,另一个是 apps_events_attributes 。第一个的id是第二个的外键,并且有许多关系。 app_events表有一个外键属性'app_id'字段,因此在特定应用上选择我将被重定向到其事件和属性。还有一个名为“is_standard”的字段,它实际上区分了事件类型,无论是标准还是自定义事件。

现在,我必须使用nested_form_for功能在视图层的两个不同选项卡中使用它的属性渲染特定应用程序的这些事件及其属性。用户可以通过此选项卡单击切换到标准和自定义事件。任何人都可以建议我如何实现相同的目标,并向我展示这个场景的理想流程(模型名称和检查'is_standard'的一部分,在控制器中传播相同的内容并渲染到视图中)?

顺便说一下,我可以在同一个模型上使用不同的控制器,如果我这样做,那么它是否能够为不同的事件及其属性执行相同的CRUD功能?

1 个答案:

答案 0 :(得分:0)

我把所有这一切都单独完成了,起初我的想法并不是很难,所有技巧都是由 JQuery 完成的......并且如果有人遇到与我相同的问题则分享这个概念

我的模型

class AppsEvent < ActiveRecord::Base
  belongs_to :app
  has_many :apps_events_attributes, :foreign_key => 'apps_event_id',
       :class_name => 'AppsEventsAttribute',
       :dependent => :destroy
  accepts_nested_attributes_for :apps_events_attributes,
                            :reject_if => lambda { |a| (a[:name].blank? &&    a[:description].blank?) },
                            :allow_destroy => true
  validates_presence_of :description
  validates_presence_of :name
  validates_presence_of :code
  validates_presence_of :apps_events_attributes, :message => "can't be empty"
end  

class AppsEventsAttribute < ActiveRecord::Base
  set_table_name :apps_events_attributes
  belongs_to :apps_event, :foreign_key => 'apps_event_id'
  attr_accessible :id, :apps_event_id, :name, :description, :attribute_type, :is_std, :created_at, :updated_at

  def type
    self.attribute_type
  end
end  

和我的控制器是......

class AppsEventsController < ApplicationController
  layout :layout_by_resource
  before_filter :initialize_default_app
  before_filter :check_permission
  before_filter :load

  def load
    @app = current_user.find_app(params[:app_id])
    @apps_events = AppsEvent.where(:app_id => @app.id)
    @apps_event = AppsEvent.new
  end

  def index
    @app = current_user.find_app(params[:app_id])
    @default_app = App.default(current_user)
    @apps_events = AppsEvent.where(:app_id => @app.id)
    @apps_event_jsons = Hash.new
    @apps_events.each do |app_event|
      json = Hash.new
      json['User_ID'] = 548741213
      json['Session_ID'] = 2568639390
      json['Action_Type'] = app_event.code
      json['eventsData'] = {}

      app_event.apps_events_attributes.each do |apps_event_attributes|
        if (apps_event_attributes.attribute_type == 'Integer')
          json['eventsData'][apps_event_attributes.name] = 1234
        elsif (apps_event_attributes.attribute_type == 'Float')
          json['eventsData'][apps_event_attributes.name] = 1234.23
        else
          json['eventsData'][apps_event_attributes.name] = 'abcd'
        end
      end

      @apps_event_jsons[app_event.id] = json
    end
  end

  def new
    @apps_event = AppsEvent.new
    @app = current_user.find_app(params[:app_id])
    @apps_event.app_id = @app.id
    @apps_event.apps_events_attributes.build
    @action = 'create'
    render 'edit'
  end

  def edit
    @app = current_user.find_app(params[:app_id])
    @apps_event = AppsEvent.find(params[:id])
    @action = 'update'
  end

  def create
    @apps_event = AppsEvent.new(params[:apps_event])
    @show_custom_event = 'true'
    @apps_event.name = @apps_event.name.strip
    respond_to do |format|
      if @apps_event.save
        format.html {
          redirect_to("/app/#{params[:apps_event][:app_id]}/apps_events",
                  :notice => "Successfully created #{@apps_event.name} custom definition.")
        }
        format.js {
          flash[:notice] = 'Successfully created event.'
          @apps_events = AppsEvent.where(:app_id => @app.id)
        }
      else
        @app = current_user.find_app(params[:app_id])

        if (@apps_event.apps_events_attributes == nil ||   @apps_event.apps_events_attributes.size <= 0)
          @apps_event.apps_events_attributes.build
        end

        @apps_event.populate_code
        @action = 'create'
        format.html {
          redirect_to("/app/#{params[:apps_event][:app_id]}/apps_events",
                  :alert => "Error in creating #{@apps_event.name} custom definition.")
        }
        format.js
      end
    end
  end

  def update
    @apps_event = AppsEvent.find(params[:apps_event][:id])
    params[:apps_event][:name] = params[:apps_event][:name].strip

    respond_to do |format|
      if @apps_event.update_attributes(params[:apps_event])
        format.html {
          if(@apps_event.is_std == 'y')
            redirect_to("/app/#{params[:apps_event][:app_id]}/apps_events",
                  :notice => "Successfully updated #{@apps_event.name} standard definition.")
          else
            redirect_to("/app/#{params[:apps_event][:app_id]}/apps_events",
                    :notice => "Successfully updated #{@apps_event.name} custom definition.")
          end
        }
        format.js {
          flash[:notice] = 'Successfully updated event.'
          @apps_events = AppsEvent.where(:app_id => @app.id)
          render :nothing => true
        }
      else
        @app = current_user.find_app(params[:app_id])

        if (@apps_event.apps_events_attributes == nil || @apps_event.apps_events_attributes.size <= 0)
          @apps_event.apps_events_attributes.build
        end

        @apps_event.populate_code
        @action = "update"
        format.html {
          if(@apps_event.is_std == 'y')
            redirect_to("/app/#{params[:apps_event][:app_id]}/apps_events",
                  :alert => "Error in updating #{@apps_event.name} standard definition.")
          else
            redirect_to("/app/#{params[:apps_event][:app_id]}/apps_events",
                    :alert => "Error in updating #{@apps_event.name} custom definition.")
          end
        }
        format.js
      end
    end
  end

  def delete
    if AppsEvent.delete(params[:id])
      redirect_to "/app/#{params[:app_id]}/apps_events", :notice => "Successfully deleted #{@apps_event.name} custom definition."
    else
      redirect_to "/app/#{params[:app_id]}/apps_events",
              :alert => "Error in deleting #{@apps_event.name} custom definition."
    end
  end
end  

我有5个视图文件,其中index.html.erb,edit.js.erb,_form_custom.html.erb,_form_standard.html.erb和_events.html.erb旁边还有一个帮助文件进行更新,通过设置remote =&gt;使用ajax调用创建和删除真正。在索引文件中,我正在部分渲染所有事件(_events.html.erb),在这里我完成了诀窍:P
我的 _events.html.erb

<% for apps_event in @apps_events %>
  <% if (apps_event.is_std == 'y') %>
    <div class="standardEvent showStandard">
      <ul>
        <li class="column_1"><span style="font-weight: bold;"><%= apps_event.name %></span></li>
        <li class="column_2"><span><%= apps_event.code %></span></li>
        <li class="column_3"><span><%= apps_event.description %></span></li>
        <li class="column_4">
          <%= link_to edit_apps_event(apps_event) %>
        </li>
        <li class="column_5">

        </li>
      </ul>
    </div>
  <% else %>
    <div class="customEvent showCustom" style="display:none">
      <ul>
        <li class="column_1"><span style="font-weight: bold;"><%= apps_event.name %></span></li>
        <li class="column_2"><span><%= apps_event.code %></span></li>
        <li class="column_3"><span><%= apps_event.description %></span></li>
        <li class="column_4">
          <%= link_to edit_apps_event(apps_event) %>
        </li>
        <li class="column_5">
          <%= remove_apps_event_prompt_link(apps_event) %>
        </li>
      </ul>
    </div>
  <% end %>
  <div class="clrBoth"></div>
<% end %>

现在你可以找出左边部分的意思 - 用于隐藏或显示div的JQuery部分。