Skip to content

minnowlab/cast_about_for

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

64 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

CastAboutFor

CastAboutFor allows you easily and reliably query ActiveRecord.

Installation

Install this gem by adding this to your Gemfile:

gem 'cast_about_for'

Then run:

bundle install

Updating is as simple as bundle update cast_about_for.

Usage

Setting the Query Column

First, you must set some query colums in your model using the cast_about_for_params macro:

class Product < ActiveRecord::Base
  cast_about_for_params equal: ['name', 'sex']

  # ...
end

Start the Query:

You can always use the #cast_about_for class method to query:

def index
  @products = Product.cast_about_for(params)
end

Want to count records? Simple:

  Product.cast_about_for(params).count

cast_about_for_params Configure

Equal

If you want to use a column query the SQL look like SELECT "products".* FROM "products" WHERE (name = 'iPhone'), you can pass it as an option:

# params = {name: 'iPhone'}
# Product.cast_about_for(params)

class Product < ActiveRecord::Base
  cast_about_for_params equal: ['name']

  # ...
end

Or you want to alias of the name argument in params

# params = { nick_name: "iPhone"}
# Product.cast_about_for(params)

class Product < ActiveRecord::Base
  cast_about_for_params equal: [{name: "nick_name"}]

  # ...
end

And you have other alias arguments , you can do it like below.

# params = { nick_name: "iPhone", info: "sales", price: "600"}
# Product.cast_about_for(params)

class Product < ActiveRecord::Base
  cast_about_for_params equal: [{name: "nick_name"}, {information: "info"}, price]

  # ...
end

Like

If you want to use a column query the SQL look like SELECT "products".* FROM "products" WHERE (introduce LIKE '%To%'), you can pass it as an option:

# params = {introduce: 'To'}
# Product.cast_about_for(params)

class Product < ActiveRecord::Base
  cast_about_for_params like: ['introduce']

  # ...
end

Suck as Equal. If you want alias of introduce argument, you can

class Product < ActiveRecord::Base
  cast_about_for_params like: [{introduce: 'intr'}]

  # ...
end

After

If you want to use a column query the SQL look like SELECT "products".* FROM "products" WHERE (production_date >= '2016-07-05 13:09:00'), you can pass it as an option:

# params = {production_started_at: '2016-07-05 13:09:00', by_time: 'production_date'}
# Product.cast_about_for(params)

class Product < ActiveRecord::Base
  cast_about_for_params after: { field: 'by_time', time: "production_started_at" }

  # ...
end

In addition, if your params not include by_time option. Like params = {production_started_at: '2016-07-05 13:09:00'}, the query column will be set the default column created_at.

If you want to use multiple column query the SQL look like SELECT "products".* FROM "products" WHERE (production_date >= '2016-07-05 13:09:00') AND (created_at >= '2016-07-04'), you can do it like this:

# params = {production_started_at: '2016-07-05 13:09:00', by_time: 'production_date', create_field: 'created_at', production_created_at: '2016-07-04'}
# Product.cast_about_for(params)

class Product < ActiveRecord::Base
  cast_about_for_params after: [{field: 'by_time', time: "production_started_at"}, { field: 'create_field', time: "production_created_at"}]

  # ...
end

If you want more columns to query, you can code it like this pattern: cast_about_for_params after: [{field: 'by_time', time: "production_started_at"}, { field: 'create_field', time: "production_created_at"}, {field: '..', time: '..'}, {...}, ...]

If you want to set the field exact column you can do it like this:

# params = {production_started_at: '2016-07-05 13:09:00'}
# Product.cast_about_for(params) # The SQL: `SELECT "products".* FROM "products" WHERE (production_date >= '2016-07-05 13:09:00')`

class Product < ActiveRecord::Base
  cast_about_for_params after: [{field: {exact: "production_date"}, time: "production_started_at"}]

  # ...
end

Before

Just like the above After. If you want to use a column query the SQL look like SELECT "products".* FROM "products" WHERE (production_date <= '2016-07-05 13:09:00'), you can pass it as an option:

# params = {production_ended_at: '2016-07-05 13:09:00', by_time: 'production_date'}
# Product.cast_about_for(params)

class Product < ActiveRecord::Base
  cast_about_for_params before: {field: 'by_time', time: 'production_ended_at'}

  # ...
end

In addition, if your params not include by_time option. Like params = {production_ended_at: '2016-07-05 13:09:00'}, the query column will be set the default column created_at.

If you want to use multiple column query the SQL look like SELECT "products".* FROM "products" WHERE (production_date <= '2016-07-05 13:09:00') AND (created_at <= '2016-07-04'), you can do it like this:

# params = {production_ended_at: '2016-07-05 13:09:00', by_time: 'production_date', create_field: 'created_at', production_created_at: '2016-07-04'}
# Product.cast_about_for(params)

class Product < ActiveRecord::Base
  cast_about_for_params after: [{field: 'by_time', time: "production_ended_at"}, { field: 'create_field', time: "production_created_at"}]

  # ...
end

If you want more columns to query, you can code it like this pattern: cast_about_for_params after: [{field: 'by_time', time: "production_ended_at"}, { field: 'create_field', time: "production_created_at"}, {field: '..', time: '..'}, {...}, ...]

If you want to set the field exact column you can do it like this:

# params = {production_ended_at: '2016-07-05 13:09:00'}
# Product.cast_about_for(params) # The SQL: `SELECT "products".* FROM "products" WHERE (production_date <= '2016-07-05 13:09:00')`

class Product < ActiveRecord::Base
  cast_about_for_params after: [{field: {exact: "production_date"}, time: "production_ended_at"}]

  # ...
end

Enum

If you have a column use enum, you can pass it as an option:

# params = {category: "food"}
# Product.cast_about_for(params)

class Product < ActiveRecord::Base
  enum category: {food: 0}
  cast_about_for_params enum: ['category']

  # ...
end

Suck as Equal. If you want alias of category argument, you can

# params = {other_name: "food"}
# Product.cast_about_for(params)

class Product < ActiveRecord::Base
  cast_about_for_params enum: [{category: 'other_name'}]

  # ...
end

Comparison

If you want to compare a column, the sql like this: The SQL: SELECT "products".* FROM "products" WHERE (weight >= '100' AND weight <= '1000') you can do it like this:

# params = {weight_min: 100, weight_max: 1000}
# Product.cast_about_for(params)

class Product < ActiveRecord::Base
  cast_about_for_params comparison: [{"weight >= ?" => "weight_min"}, {"weight <= ?" => "weight_max"}]

end

###Includes If you want to includes other models, you can do it like this

class Product < ActiveRecord::Base
  cast_about_for_params includes: [:user, :items]

#This will make `product` include `user` and `items` automatically
#Like:  Product.includes(:user, :items)
end

###Joins

If you want to join a model you can do it like this:

Example 1 

class Product <  ActiveRecord::Base
  cast_about_for_params joins: [{user: [equal: :name]}]
  
end

# params = {name: "user"}
# Product.cast_about_for(params)
# It will be generates like this: Product.joins(:user).where("users.name = ?", "user")
# The sql would like this: `SELECT "products".* FROM "products" INNER JOIN "users" ON "users"."id" = "products"."user_id" WHERE (users.name = 'user')`

If you want to query the condition of "LIKE", do it like this

class Product <  ActiveRecord::Base
  cast_about_for_params joins: [{user: [like: :name]}]
  
end
Then the sql would be like this:  `SELECT "products".* FROM "products" INNER JOIN "users" ON "users"."id" = "products"."user_id" WHERE (users.name Like 'user')`


--------
Example 2
If you want to nickname the `name` of the params like: 
# params = {user_name: "user"}
# Product.cast_about_for(params)

class Product <  ActiveRecord::Base
  cast_about_for_params joins: [{user: [equal: {name: :user_name}]}]
  
end

# Also will generates like this: Product.joins(:user).where("users.name = ?", "user") 
# The sql would like this: `SELECT "products".* FROM "products" INNER JOIN "users" ON "users"."id" = "products"."user_id" WHERE (users.name = 'user')`

--------
Example 3
If multiple user columns that you want to query, you can do it like this:
# params = {name: "user", age: 18}
# Product.cast_about_for(params)

class Product <  ActiveRecord::Base
  cast_about_for_params joins: [{user: [equal: [:name, :age]}]
  
end
# Also will generates like this: Product.joins(:user).where("users.name = ? AND users.age = ?", "user", "18") 
# The sql would like this: `SELECT "products".* FROM "products" INNER JOIN "users" ON "users"."id" = "products"."user_id" WHERE (users.name = 'user' AND users.age = 18)`


If you want to nickname the params:
# params = {user_name: "user", user_age: 18}
# Product.cast_about_for(params)
class Product <  ActiveRecord::Base
  cast_about_for_params joins: [{user: [equal: [{name: :user_name}, {age: :user_age}]}]
  
end

--------
Example 4
You can use the `equal` and `like` at the same time:
class Product <  ActiveRecord::Base
  cast_about_for_params joins: [{user: [equal: :age], [like: :name]}]
  
end

`OR`
class Product <  ActiveRecord::Base
  cast_about_for_params joins: [{user: [equal: [:age, :height]], [like: [:name, :roles]]}]
  
end

--------
Example 5
Nested joins:

Now, I have `product` `user` `company` models, 

class Product <  ActiveRecord::Base
  belongs_to :user
end

class User <  ActiveRecord::Base
  belongs_to :company
  has_many :products
end

class Company <  ActiveRecord::Base
  has_many :user
end

I have company `name`, and now I want to query the products through the user who belong to the company, so I can do it like this:

class Product <  ActiveRecord::Base
  cast_about_for_params joins: [{{user: :company} => [like: {name: :company_name}]}]
  
end
# params = {company_name: "Teo"}
# Product.cast_about_for(params)
# The sql would like this:  SELECT "products".* FROM "products" INNER JOIN "users" ON "users"."id" = "products"."user_id" INNER JOIN "companies" ON "companies"."id" = "users"."company_id" WHERE (companies.name LIKE 'Teo')

Advanced Usage

JSON API

If you are using JSON API, you can set in the #cast_about_for:

  Product.cast_about_for(params, jsonapi: true) # JSON API

Custom Query by Block

If want to find products where belong to some people, you can do it like:

  params = { user_name: 'hello', age: 20 }

  Product.cast_about_for(params, jsonapi: true) do |products, cast_params|
    products = products.joins(:user).where("users.name Like ?", "%#{cast_params[:user_name]}%") if cast_params[:user_name].present?
    products = products.joins(:user).where("users.age = ?", cast_params[:age]) if cast_params[:age].present?
  end

Collaborators

Thank you to the following people:

License

The gem is available as open source under the terms of the MIT License.

About

CastAboutFor allows you easily and reliably query ActiveRecord.

Resources

License

Code of conduct

Stars

Watchers

Forks

Packages

No packages published