ActiveRecord::Base Without Table

2019-01-08 10:29发布

This came up a bit ago ( rails model attributes without corresponding column in db ) but it looks like the Rails plugin mentioned is not maintained ( http://agilewebdevelopment.com/plugins/activerecord_base_without_table ). Is there no way to do this with ActiveRecord as is?

If not, is there any way to get ActiveRecord validation rules without using ActiveRecord?

ActiveRecord wants the table to exist, of course.

8条回答
来,给爷笑一个
2楼-- · 2019-01-08 10:55

Just an addition to the accepted answer:

Make your subclasses inherit the parent columns with:

class FakeAR < ActiveRecord::Base
  def self.inherited(subclass)
    subclass.instance_variable_set("@columns", columns)
    super
  end

  def self.columns
    @columns ||= []
  end

  def self.column(name, sql_type = nil, default = nil, null = true)
    columns << ActiveRecord::ConnectionAdapters::Column.new(name.to_s, default, sql_type.to_s, null)
  end

  # Overrides save to prevent exceptions.
  def save(validate = true)
    validate ? valid? : true
  end
end
查看更多
祖国的老花朵
3楼-- · 2019-01-08 10:56

This is a search form that presents an object called criteria that has a nested period object with beginning and end attributes.

The action in the controller is really simple yet it loads values from nested objects on the form and re-renders the same values with error messages if necessary.

Works on Rails 3.1.

The model:

class Criteria < ActiveRecord::Base
  class << self

    def column_defaults
      {}
    end

    def column_names
      []
    end
  end # of class methods

  attr_reader :period

  def initialize values
    values ||= {}
    @period = Period.new values[:period] || {}
    super values
  end

  def period_attributes
    @period
  end
  def period_attributes= new_values
    @period.attributes = new_values
  end
end

In the controller:

def search
  @criteria = Criteria.new params[:criteria]
end

In the helper:

def criteria_index_path ct, options = {}
  url_for :action => :search
end

In the view:

<%= form_for @criteria do |form| %>
  <%= form.fields_for :period do |prf| %>
    <%= prf.text_field :beginning_as_text %>
    <%= prf.text_field :end_as_text %>
  <% end %>
  <%= form.submit "Search" %>
<% end %>

Produces the HTML:

<form action="/admin/search" id="new_criteria" method="post">
  <input id="criteria_period_attributes_beginning_as_text" name="criteria[period_attributes][beginning_as_text]" type="text"> 
  <input id="criteria_period_attributes_end_as_text" name="criteria[period_attributes][end_as_text]" type="text">

Note: The action attribute provided by the helper and the nested attributes naming format that makes it so simple for the controller to load all the values at once

查看更多
登录 后发表回答