ActiveRecord::테이블이 없는 베이스
-
06-09-2019 - |
문제
이건 좀 전에 나왔는데( DB에 해당 열이 없는 Rails 모델 속성 ) 그러나 언급된 Rails 플러그인은 유지 관리되지 않는 것 같습니다( http://agilewebdevelopment.com/plugins/activerecord_base_without_table ).ActiveRecord를 있는 그대로 사용할 수 있는 방법은 없나요?
그렇지 않은 경우 ActiveRecord를 사용하지 않고 ActiveRecord 유효성 검사 규칙을 얻을 수 있는 방법이 있습니까?
물론 ActiveRecord는 테이블이 존재하기를 원합니다.
해결책
이것은 내가 과거에 사용한 접근법입니다.
~ 안에 앱/모델/tableness.rb
class Tableless < ActiveRecord::Base
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
# Override the save method to prevent exceptions.
def save(validate = true)
validate ? valid? : true
end
end
~ 안에 앱/모델/foo.rb
class Foo < Tableless
column :bar, :string
validates_presence_of :bar
end
~ 안에 스크립트/콘솔
Loading development environment (Rails 2.2.2)
>> foo = Foo.new
=> #<Foo bar: nil>
>> foo.valid?
=> false
>> foo.errors
=> #<ActiveRecord::Errors:0x235b270 @errors={"bar"=>["can't be blank"]}, @base=#<Foo bar: nil>>
다른 팁
유효성 검사는 단순히 ActiveRecord 내의 모듈입니다. 비 ActiveRecord 모델에 믹싱 해 보셨습니까?
class MyModel
include ActiveRecord::Validations
# ...
end
나는 "테이블이 없는 레일 3.1 모델"을 검색할 때 Google의 첫 번째 결과 중 하나이기 때문에 답변이 많을수록 더 좋다고 생각합니다.
ActiveRecord::Validations를 포함하면서 ActiveRecord::Base를 사용하지 않고 동일한 것을 구현했습니다.
주요 목표는 모든 것이 형식적으로 작동하도록 하는 것이었고 아래에는 어디에도 저장되지 않지만 우리 모두가 알고 사랑하는 검증을 사용하여 검증할 수 있는 샘플 결제가 포함되어 있습니다.
class Payment
include ActiveModel::Validations
attr_accessor :cc_number, :payment_type, :exp_mm, :exp_yy, :card_security, :first_name, :last_name, :address_1, :address_2, :city, :state, :zip_code, :home_telephone, :email, :new_record
validates_presence_of :cc_number, :payment_type, :exp_mm, :exp_yy, :card_security, :first_name, :last_name, :address_1, :address_2, :city, :state
def initialize(options = {})
if options.blank?
new_record = true
else
new_record = false
end
options.each do |key, value|
method_object = self.method((key + "=").to_sym)
method_object.call(value)
end
end
def new_record?
return new_record
end
def to_key
end
def persisted?
return false
end
end
오늘 이 문제를 해결하기 위해 몇 시간을 보냈기 때문에 이것이 누군가에게 도움이 되기를 바랍니다.
업데이트: 레일 3의 경우 이것은 매우 쉽게 수행 할 수 있습니다. Rails 3+에서는 새로운 것을 사용할 수 있습니다 ActiveModel
모듈 및 하위 모듈. 지금은 작동해야합니다.
class Tableless
include ActiveModel::Validations
attr_accessor :name
validates_presence_of :name
end
자세한 내용은 확인할 수 있습니다 Railscast (또는 Asciicasts에서 그것에 대해 읽으십시오) 주제와 이것에 대해서도 Yehuda Katz의 블로그 게시물.
오래된 답변은 다음과 같습니다.
이전 의견에서 John Topley가 제안한 솔루션에 이것을 추가해야 할 수도 있습니다.
class Tableless
class << self
def table_name
self.name.tableize
end
end
end
class Foo < Tableless; end
Foo.table_name # will return "foos"
필요한 경우 "가짜"테이블 이름을 제공합니다. 이 방법이 없으면 Foo::table_name
"Tableselesses"로 평가됩니다.
나는이 링크가 아름답게 작동하는 것을 발견했습니다.
허용 된 답변에 추가 :
서브 클래스를 다음과 함께 상위 열을 상속 받으십시오.
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.1에서 작동합니다.
모델:
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
컨트롤러에서 :
def search
@criteria = Criteria.new params[:criteria]
end
도우미에서 :
def criteria_index_path ct, options = {}
url_for :action => :search
end
관점에서 :
<%= 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 %>
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">
메모: 컨트롤러가 한 번에 모든 값을로드 할 수 있도록 도우미와 중첩 된 속성 이름 지정 형식이 제공 한 조치 속성
거기 있습니다 Activerecord-tablestess 보석. Tableless ActiveRecord 모델을 만드는 것은 보석이므로 검증, 연관성, 유형을 지원합니다. 활성 레코드 2.3, 3.0, 3.2를 지원합니다
Rails 3.x (ActiveModel 사용)에서 수행하는 권장 방법은 연관성이나 유형을 지원하지 않습니다.