Clear ORM
Search…
Describing your columns

Clear::Model#column

Clear offers a column macro:
1
column method_name : Type, [primary: bool], [converter: "any_string"],
2
[column_name: "any_string"], [presence: bool]
Copied!
The arguments action is defined as below:
Argument name
Description
primary
Whether this column should be setup as primary key or not. Only one primary key per model is permitted. Primary key are necessary for handling relations and some features (e.g default sorting)
Default: false
converter
Use a specific data converter between Clear and PostgreSQL to handle this column.
<b></b>
Default: Will lookup for the converter related to the type of the column; primitives and commons type are already mapped, while complex type and structures must be mapped manually. See the section about converters for more information.
column_name
In the case the column name is different from the field in Clear (e.g. the name is a reserved keyword in Crystal Lang), you might want to change it here.
Default: Same name between the column in PostgreSQL and the property in your model
presence
Enable of disable the presence check done on validation and insertion of the model in the database. When your column has a default value setup by PostgreSQL (like a serial type), you want to setup presence to false.
Default: true unless the type is nilable.
Clear use a column assignation system which provide safeguard against NilException while keeping possibility to fetch semi-fetched model. For example, you may want to fetch only the first_name and last_name of a User through the database:
1
User.query.select("first_name, last_name").each do |usr|
2
puts "User: #{usr.first_name} #{usr.last_name}"
3
end
Copied!
But what if by mistake your code call a non fetched field ?
1
User.query.select("first_name, last_name").each do |usr|
2
# This will throw an exception !
3
puts "User: #{usr.id}"
4
end
Copied!
Name
Description
xxx_column.changed?
Return true
false whether the column as changed since the last database fetch
xxx_column.has_db_default?
Return true if the presence check is set to false
xxx_column.name
Return the name of the field in the database.
xxx_column.old_value
In case of change, return the previous value, before the change
xxx_column.revert
Return the column to it's initial state; changed flag is set to false and value become old_value
xxx_column.clear
The column become in non-present state (e.g. wasn't fetched)
xxx_column.defined?
Return true if the column has a value, false otherwise
xxx_column.value
Return the column value. Raise an error if the column is in a non-present state. Equivalent to self.xxx
xxx_column.value(default)
Return the current column value, OR default if the column is in a non-present state

Column types Clear already map different types of column from PostgreSQL to Crystal:

Crystal
PostgreSQL
String
text
UUID
uuid
Bool
boolean
Int8
byte
Int16
short
Int32
int, serial
Int64
bigint, bigserial
Array(Type)
type[] (note: type can be of any primitives above)
BigDecimal
numeric
JSON::Any
jsonb
Time
timestamp without time zone

Using BigDecimal (in Model) and Numeric (in Migrations)

BigDecimal (in .cr) is mapped to Numeric (in pg) in migration columns (i.e. declaring column data type as "bigdecimal" would be equal to the column being declared with type "numeric", if you wish to specify precision, and scale, please use "numeric(precision, scale)" or "numeric(precision)" (with scale defaulting to 0), instead of "bigdecimal")
Please take note that PostgreSQL will throw a numeric field overflow (and in Clear: Clear::SQl::Error) if you INSERT into the database a BigDecimal/ numeric value with the integer part (to the left of the radix point) of a size that is bigger than the precision that is specified in the numeric type that you declare. This can be seen from the following example taken from specs:
1
class Data
2
include Clear::Model
3
4
column id : Int32, primary: true, presence: false
5
column num3 : BigDecimal?
6
column num4 : BigDecimal?
7
end
8
9
class ModelSpecMigration123
10
include Clear::Migration
11
12
def change(dir)
13
create_table(:model_spec_data) do |t|
14
t.column "num3", "numeric(9)"
15
t.column "num4", "numeric(8)"
16
end
17
end
18
end
19
20
data = Data.new
21
big_number = BigDecimal.new(BigInt.new("-1029387192083710928371092837019283701982370918237".to_big_i), 40) # this is the same as "-102938719.2083710928371092837019283701982370918237"
Copied!
The following case would not throw an error
1
data.num3 = big_number
2
data.save!
Copied!
However this case would throw an error
1
data.num4 = big_number
2
data.save!
Copied!
Last modified 10mo ago