Skip to main content

Home/ Larvata/ Group items tagged ruby

Rss Feed Group items tagged

張 旭

Active Record Associations - Ruby on Rails Guides - 0 views

  • With Active Record associations, we can streamline these - and other - operations by declaratively telling Rails that there is a connection between the two models.
  • belongs_to has_one has_many has_many :through has_one :through has_and_belongs_to_many
  • an association is a connection between two Active Record models
  • ...195 more annotations...
  • Associations are implemented using macro-style calls, so that you can declaratively add features to your models
  • A belongs_to association sets up a one-to-one connection with another model, such that each instance of the declaring model "belongs to" one instance of the other model.
  • belongs_to associations must use the singular term.
  • belongs_to
  • A has_one association also sets up a one-to-one connection with another model, but with somewhat different semantics (and consequences).
  • This association indicates that each instance of a model contains or possesses one instance of another model
  • belongs_to
  • A has_many association indicates a one-to-many connection with another model.
  • This association indicates that each instance of the model has zero or more instances of another model.
  • belongs_to
  • A has_many :through association is often used to set up a many-to-many connection with another model
  • This association indicates that the declaring model can be matched with zero or more instances of another model by proceeding through a third model.
  • through:
  • through:
  • The collection of join models can be managed via the API
  • new join models are created for newly associated objects, and if some are gone their rows are deleted.
  • The has_many :through association is also useful for setting up "shortcuts" through nested has_many associations
  • A has_one :through association sets up a one-to-one connection with another model. This association indicates that the declaring model can be matched with one instance of another model by proceeding through a third model.
  • A has_and_belongs_to_many association creates a direct many-to-many connection with another model, with no intervening model.
  • id: false
  • The has_one relationship says that one of something is yours
  • using t.references :supplier instead.
  • declare a many-to-many relationship is to use has_many :through. This makes the association indirectly, through a join model
  • set up a has_many :through relationship if you need to work with the relationship model as an independent entity
  • set up a has_and_belongs_to_many relationship (though you'll need to remember to create the joining table in the database).
  • use has_many :through if you need validations, callbacks, or extra attributes on the join model
  • With polymorphic associations, a model can belong to more than one other model, on a single association.
  • belongs_to :imageable, polymorphic: true
  • a polymorphic belongs_to declaration as setting up an interface that any other model can use.
    • 張 旭
       
      _id 記錄的是不同類型的外連鍵 id;_type 記錄的是不同類型的表格名稱。
  • In designing a data model, you will sometimes find a model that should have a relation to itself
  • add a references column to the model itself
  • Controlling caching Avoiding name collisions Updating the schema Controlling association scope Bi-directional associations
  • All of the association methods are built around caching, which keeps the result of the most recent query available for further operations.
  • it is a bad idea to give an association a name that is already used for an instance method of ActiveRecord::Base. The association method would override the base method and break things.
  • You are responsible for maintaining your database schema to match your associations.
  • belongs_to associations you need to create foreign keys
  • has_and_belongs_to_many associations you need to create the appropriate join table
  • If you create an association some time after you build the underlying model, you need to remember to create an add_column migration to provide the necessary foreign key.
  • Active Record creates the name by using the lexical order of the class names
  • So a join between customer and order models will give the default join table name of "customers_orders" because "c" outranks "o" in lexical ordering.
  • For example, one would expect the tables "paper_boxes" and "papers" to generate a join table name of "papers_paper_boxes" because of the length of the name "paper_boxes", but it in fact generates a join table name of "paper_boxes_papers" (because the underscore '' is lexicographically _less than 's' in common encodings).
  • id: false
  • pass id: false to create_table because that table does not represent a model
  • By default, associations look for objects only within the current module's scope.
  • will work fine, because both the Supplier and the Account class are defined within the same scope.
  • To associate a model with a model in a different namespace, you must specify the complete class name in your association declaration:
  • class_name
  • class_name
  • Active Record provides the :inverse_of option
    • 張 旭
       
      意思是說第一次比較兩者的 first_name 是相同的;但透過 c 實體修改 first_name 之後,再次比較就不相同了,因為兩個是記憶體裡面兩個不同的物件。
  • preventing inconsistencies and making your application more efficient
  • Every association will attempt to automatically find the inverse association and set the :inverse_of option heuristically (based on the association name)
  • In database terms, this association says that this class contains the foreign key.
  • In all of these methods, association is replaced with the symbol passed as the first argument to belongs_to.
  • (force_reload = false)
  • The association method returns the associated object, if any. If no associated object is found, it returns nil.
  • the cached version will be returned.
  • The association= method assigns an associated object to this object.
  • Behind the scenes, this means extracting the primary key from the associate object and setting this object's foreign key to the same value.
  • The build_association method returns a new object of the associated type
  • but the associated object will not yet be saved.
  • The create_association method returns a new object of the associated type
  • once it passes all of the validations specified on the associated model, the associated object will be saved
  • raises ActiveRecord::RecordInvalid if the record is invalid.
  • dependent
  • counter_cache
  • :autosave :class_name :counter_cache :dependent :foreign_key :inverse_of :polymorphic :touch :validate
  • finding the number of belonging objects more efficient.
  • Although the :counter_cache option is specified on the model that includes the belongs_to declaration, the actual column must be added to the associated model.
  • add a column named orders_count to the Customer model.
  • :destroy, when the object is destroyed, destroy will be called on its associated objects.
  • deleted directly from the database without calling their destroy method.
  • Rails will not create foreign key columns for you
  • The :inverse_of option specifies the name of the has_many or has_one association that is the inverse of this association
  • set the :touch option to :true, then the updated_at or updated_on timestamp on the associated object will be set to the current time whenever this object is saved or destroyed
  • specify a particular timestamp attribute to update
  • If you set the :validate option to true, then associated objects will be validated whenever you save this object
  • By default, this is false: associated objects will not be validated when this object is saved.
  • where includes readonly select
  • make your code somewhat more efficient
  • no need to use includes for immediate associations
  • will be read-only when retrieved via the association
  • The select method lets you override the SQL SELECT clause that is used to retrieve data about the associated object
  • using the association.nil?
  • Assigning an object to a belongs_to association does not automatically save the object. It does not save the associated object either.
  • In database terms, this association says that the other class contains the foreign key.
  • the cached version will be returned.
  • :as :autosave :class_name :dependent :foreign_key :inverse_of :primary_key :source :source_type :through :validate
  • Setting the :as option indicates that this is a polymorphic association
  • :nullify causes the foreign key to be set to NULL. Callbacks are not executed.
  • It's necessary not to set or leave :nullify option for those associations that have NOT NULL database constraints.
  • The :source_type option specifies the source association type for a has_one :through association that proceeds through a polymorphic association.
  • The :source option specifies the source association name for a has_one :through association.
  • The :through option specifies a join model through which to perform the query
  • more efficient by including representatives in the association from suppliers to accounts
  • When you assign an object to a has_one association, that object is automatically saved (in order to update its foreign key).
  • If either of these saves fails due to validation errors, then the assignment statement returns false and the assignment itself is cancelled.
  • If the parent object (the one declaring the has_one association) is unsaved (that is, new_record? returns true) then the child objects are not saved.
  • If you want to assign an object to a has_one association without saving the object, use the association.build method
  • collection(force_reload = false) collection<<(object, ...) collection.delete(object, ...) collection.destroy(object, ...) collection=(objects) collection_singular_ids collection_singular_ids=(ids) collection.clear collection.empty? collection.size collection.find(...) collection.where(...) collection.exists?(...) collection.build(attributes = {}, ...) collection.create(attributes = {}) collection.create!(attributes = {})
  • In all of these methods, collection is replaced with the symbol passed as the first argument to has_many, and collection_singular is replaced with the singularized version of that symbol.
  • The collection<< method adds one or more objects to the collection by setting their foreign keys to the primary key of the calling model
  • The collection.delete method removes one or more objects from the collection by setting their foreign keys to NULL.
  • objects will be destroyed if they're associated with dependent: :destroy, and deleted if they're associated with dependent: :delete_all
  • The collection.destroy method removes one or more objects from the collection by running destroy on each object.
  • The collection_singular_ids method returns an array of the ids of the objects in the collection.
  • The collection_singular_ids= method makes the collection contain only the objects identified by the supplied primary key values, by adding and deleting as appropriate
  • The default strategy for has_many :through associations is delete_all, and for has_many associations is to set the foreign keys to NULL.
  • The collection.clear method removes all objects from the collection according to the strategy specified by the dependent option
  • uses the same syntax and options as ActiveRecord::Base.find
  • The collection.where method finds objects within the collection based on the conditions supplied but the objects are loaded lazily meaning that the database is queried only when the object(s) are accessed.
  • The collection.build method returns one or more new objects of the associated type. These objects will be instantiated from the passed attributes, and the link through their foreign key will be created, but the associated objects will not yet be saved.
  • The collection.create method returns a new object of the associated type. This object will be instantiated from the passed attributes, the link through its foreign key will be created, and, once it passes all of the validations specified on the associated model, the associated object will be saved.
  • :as :autosave :class_name :dependent :foreign_key :inverse_of :primary_key :source :source_type :through :validate
  • :delete_all causes all the associated objects to be deleted directly from the database (so callbacks will not execute)
  • :nullify causes the foreign keys to be set to NULL. Callbacks are not executed.
  • where includes readonly select
  • :conditions :through :polymorphic :foreign_key
  • By convention, Rails assumes that the column used to hold the primary key of the association is id. You can override this and explicitly specify the primary key with the :primary_key option.
  • The :source option specifies the source association name for a has_many :through association.
  • You only need to use this option if the name of the source association cannot be automatically inferred from the association name.
  • The :source_type option specifies the source association type for a has_many :through association that proceeds through a polymorphic association.
  • The :through option specifies a join model through which to perform the query.
  • has_many :through associations provide a way to implement many-to-many relationships,
  • By default, this is true: associated objects will be validated when this object is saved.
  • where extending group includes limit offset order readonly select uniq
  • If you use a hash-style where option, then record creation via this association will be automatically scoped using the hash
  • The extending method specifies a named module to extend the association proxy.
  • Association extensions
  • The group method supplies an attribute name to group the result set by, using a GROUP BY clause in the finder SQL.
  • has_many :line_items, -> { group 'orders.id' },                        through: :orders
  • more efficient by including line items in the association from customers to orders
  • The limit method lets you restrict the total number of objects that will be fetched through an association.
  • The offset method lets you specify the starting offset for fetching objects via an association
  • The order method dictates the order in which associated objects will be received (in the syntax used by an SQL ORDER BY clause).
  • Use the distinct method to keep the collection free of duplicates.
  • mostly useful together with the :through option
  • -> { distinct }
  • .all.inspect
  • If you want to make sure that, upon insertion, all of the records in the persisted association are distinct (so that you can be sure that when you inspect the association that you will never find duplicate records), you should add a unique index on the table itself
  • unique: true
  • Do not attempt to use include? to enforce distinctness in an association.
  • multiple users could be attempting this at the same time
  • checking for uniqueness using something like include? is subject to race conditions
  • When you assign an object to a has_many association, that object is automatically saved (in order to update its foreign key).
  • If any of these saves fails due to validation errors, then the assignment statement returns false and the assignment itself is cancelled.
  • If the parent object (the one declaring the has_many association) is unsaved (that is, new_record? returns true) then the child objects are not saved when they are added
  • All unsaved members of the association will automatically be saved when the parent is saved.
  • assign an object to a has_many association without saving the object, use the collection.build method
  • collection(force_reload = false) collection<<(object, ...) collection.delete(object, ...) collection.destroy(object, ...) collection=(objects) collection_singular_ids collection_singular_ids=(ids) collection.clear collection.empty? collection.size collection.find(...) collection.where(...) collection.exists?(...) collection.build(attributes = {}) collection.create(attributes = {}) collection.create!(attributes = {})
  • If the join table for a has_and_belongs_to_many association has additional columns beyond the two foreign keys, these columns will be added as attributes to records retrieved via that association.
  • Records returned with additional attributes will always be read-only
  • If you require this sort of complex behavior on the table that joins two models in a many-to-many relationship, you should use a has_many :through association instead of has_and_belongs_to_many.
  • aliased as collection.concat and collection.push.
  • The collection.delete method removes one or more objects from the collection by deleting records in the join table
  • not destroy the objects
  • The collection.destroy method removes one or more objects from the collection by running destroy on each record in the join table, including running callbacks.
  • not destroy the objects.
  • The collection.clear method removes every object from the collection by deleting the rows from the joining table.
  • not destroy the associated objects.
  • The collection.find method finds objects within the collection. It uses the same syntax and options as ActiveRecord::Base.find.
  • The collection.where method finds objects within the collection based on the conditions supplied but the objects are loaded lazily meaning that the database is queried only when the object(s) are accessed.
  • The collection.exists? method checks whether an object meeting the supplied conditions exists in the collection.
  • The collection.build method returns a new object of the associated type.
  • the associated object will not yet be saved.
  • the associated object will be saved.
  • The collection.create method returns a new object of the associated type.
  • it passes all of the validations specified on the associated model
  • :association_foreign_key :autosave :class_name :foreign_key :join_table :validate
  • The :foreign_key and :association_foreign_key options are useful when setting up a many-to-many self-join.
  • Rails assumes that the column in the join table used to hold the foreign key pointing to the other model is the name of that model with the suffix _id added.
  • If you set the :autosave option to true, Rails will save any loaded members and destroy members that are marked for destruction whenever you save the parent object.
  • By convention, Rails assumes that the column in the join table used to hold the foreign key pointing to this model is the name of this model with the suffix _id added.
  • By default, this is true: associated objects will be validated when this object is saved.
  • where extending group includes limit offset order readonly select uniq
  • set conditions via a hash
  • In this case, using @parts.assemblies.create or @parts.assemblies.build will create orders where the factory column has the value "Seattle"
  • If you use a hash-style where, then record creation via this association will be automatically scoped using the hash
  • using a GROUP BY clause in the finder SQL.
  • Use the uniq method to remove duplicates from the collection.
  • assign an object to a has_and_belongs_to_many association, that object is automatically saved (in order to update the join table).
  • If any of these saves fails due to validation errors, then the assignment statement returns false and the assignment itself is cancelled.
  • If the parent object (the one declaring the has_and_belongs_to_many association) is unsaved (that is, new_record? returns true) then the child objects are not saved when they are added.
  • If you want to assign an object to a has_and_belongs_to_many association without saving the object, use the collection.build method.
  • Normal callbacks hook into the life cycle of Active Record objects, allowing you to work with those objects at various points
  • define association callbacks by adding options to the association declaration
  • Rails passes the object being added or removed to the callback.
  • stack callbacks on a single event by passing them as an array
  • If a before_add callback throws an exception, the object does not get added to the collection.
  • if a before_remove callback throws an exception, the object does not get removed from the collection
  • extend these objects through anonymous modules, adding new finders, creators, or other methods.
  • order_number
  • use a named extension module
  • proxy_association.owner returns the object that the association is a part of.
張 旭

Active Record Validations - Ruby on Rails Guides - 0 views

  • validates :name, presence: true
  • Validations are used to ensure that only valid data is saved into your database
  • Model-level validations are the best way to ensure that only valid data is saved into your database.
  • ...117 more annotations...
  • native database constraints
  • client-side validations
  • controller-level validations
  • Database constraints and/or stored procedures make the validation mechanisms database-dependent and can make testing and maintenance more difficult
  • Client-side validations can be useful, but are generally unreliable
  • combined with other techniques, client-side validation can be a convenient way to provide users with immediate feedback
  • it's a good idea to keep your controllers skinny
  • model-level validations are the most appropriate in most circumstances.
  • Active Record uses the new_record? instance method to determine whether an object is already in the database or not.
  • Creating and saving a new record will send an SQL INSERT operation to the database. Updating an existing record will send an SQL UPDATE operation instead. Validations are typically run before these commands are sent to the database
  • The bang versions (e.g. save!) raise an exception if the record is invalid.
  • save and update return false
  • create just returns the object
  • skip validations, and will save the object to the database regardless of its validity.
  • be used with caution
  • update_all
  • save also has the ability to skip validations if passed validate: false as argument.
  • save(validate: false)
  • valid? triggers your validations and returns true if no errors
  • After Active Record has performed validations, any errors found can be accessed through the errors.messages instance method
  • By definition, an object is valid if this collection is empty after running validations.
  • validations are not run when using new.
  • invalid? is simply the inverse of valid?.
  • To verify whether or not a particular attribute of an object is valid, you can use errors[:attribute]. I
  • only useful after validations have been run
  • Every time a validation fails, an error message is added to the object's errors collection,
  • All of them accept the :on and :message options, which define when the validation should be run and what message should be added to the errors collection if it fails, respectively.
  • validates that a checkbox on the user interface was checked when a form was submitted.
  • agree to your application's terms of service
  • 'acceptance' does not need to be recorded anywhere in your database (if you don't have a field for it, the helper will just create a virtual attribute).
  • It defaults to "1" and can be easily changed.
  • use this helper when your model has associations with other models and they also need to be validated
  • valid? will be called upon each one of the associated objects.
  • work with all of the association types
  • Don't use validates_associated on both ends of your associations.
    • 張 旭
       
      關聯式的物件驗證,在其中一方啟動就好了!
  • each associated object will contain its own errors collection
  • errors do not bubble up to the calling model
  • when you have two text fields that should receive exactly the same content
  • This validation creates a virtual attribute whose name is the name of the field that has to be confirmed with "_confirmation" appended.
  • To require confirmation, make sure to add a presence check for the confirmation attribute
  • this set can be any enumerable object.
  • The exclusion helper has an option :in that receives the set of values that will not be accepted for the validated attributes.
  • :in option has an alias called :within
  • validates the attributes' values by testing whether they match a given regular expression, which is specified using the :with option.
  • attribute does not match the regular expression by using the :without option.
  • validates that the attributes' values are included in a given set
  • :in option has an alias called :within
  • specify length constraints
  • :minimum
  • :maximum
  • :in (or :within)
  • :is - The attribute length must be equal to the given value.
  • :wrong_length, :too_long, and :too_short options and %{count} as a placeholder for the number corresponding to the length constraint being used.
  • split the value in a different way using the :tokenizer option:
    • 張 旭
       
      自己提供切割算字數的方式
  • validates that your attributes have only numeric values
  • By default, it will match an optional sign followed by an integral or floating point number.
  • set :only_integer to true.
  • allows a trailing newline character.
  • :greater_than
  • :greater_than_or_equal_to
  • :equal_to
  • :less_than
  • :less_than_or_equal_to
  • :odd - Specifies the value must be an odd number if set to true.
  • :even - Specifies the value must be an even number if set to true.
  • validates that the specified attributes are not empty
  • if the value is either nil or a blank string
  • validate associated records whose presence is required, you must specify the :inverse_of option for the association
  • inverse_of
  • an association is present, you'll need to test whether the associated object itself is present, and not the foreign key used to map the association
  • false.blank? is true
  • validate the presence of a boolean field
  • ensure the value will NOT be nil
  • validates that the specified attributes are absent
  • not either nil or a blank string
  • be sure that an association is absent
  • false.present? is false
  • validate the absence of a boolean field you should use validates :field_name, exclusion: { in: [true, false] }.
  • validates that the attribute's value is unique right before the object gets saved
  • a :scope option that you can use to specify other attributes that are used to limit the uniqueness check
  • a :case_sensitive option that you can use to define whether the uniqueness constraint will be case sensitive or not.
  • There is no default error message for validates_with.
  • To implement the validate method, you must have a record parameter defined, which is the record to be validated.
  • the validator will be initialized only once for the whole application life cycle, and not on each validation run, so be careful about using instance variables inside it.
  • passes the record to a separate class for validation
  • use a plain old Ruby object
  • validates attributes against a block
  • The block receives the record, the attribute's name and the attribute's value. You can do anything you like to check for valid data within the block
  • will let validation pass if the attribute's value is blank?, like nil or an empty string
  • the :message option lets you specify the message that will be added to the errors collection when validation fails
  • skips the validation when the value being validated is nil
  • specify when the validation should happen
  • raise ActiveModel::StrictValidationFailed when the object is invalid
  • You can do that by using the :if and :unless options, which can take a symbol, a string, a Proc or an Array.
  • use the :if option when you want to specify when the validation should happen
  • using eval and needs to contain valid Ruby code.
  • Using a Proc object gives you the ability to write an inline condition instead of a separate method
  • have multiple validations use one condition, it can be easily achieved using with_options.
  • implement a validate method which takes a record as an argument and performs the validation on it
  • validates_with method
  • implement a validate_each method which takes three arguments: record, attribute, and value
  • combine standard validations with your own custom validators.
  • :expiration_date_cannot_be_in_the_past,    :discount_cannot_be_greater_than_total_value
  • By default such validations will run every time you call valid?
  • errors[] is used when you want to check the error messages for a specific attribute.
  • Returns an instance of the class ActiveModel::Errors containing all errors.
  • lets you manually add messages that are related to particular attributes
  • using []= setter
  • errors[:base] is an array, you can simply add a string to it and it will be used as an error message.
  • use this method when you want to say that the object is invalid, no matter the values of its attributes.
  • clear all the messages in the errors collection
  • calling errors.clear upon an invalid object won't actually make it valid: the errors collection will now be empty, but the next time you call valid? or any method that tries to save this object to the database, the validations will run again.
  • the total number of error messages for the object.
  • .errors.full_messages.each
  • .field_with_errors
張 旭

Active Record Callbacks - Ruby on Rails Guides - 0 views

  • Active Record provides hooks into this object life cycle so that you can control your application and its data.
  • Callbacks allow you to trigger logic before or after an alteration of an object's state.
  • Callbacks are methods that get called at certain moments of an object's life cycle.
  • ...42 more annotations...
  • created
  • saved
  • updated
  • deleted
  • validated
  • loaded
  • use a macro-style class method to register them as callbacks
  • self.name = login.capitalize if name.blank?
  • registered to only fire on certain life cycle events
  • considered good practice to declare callback methods as protected or private
  • all the available Active Record callbacks,
  • after_initialize callback will be called whenever an Active Record object is instantiated, either by directly using new or when a record is loaded from the database
  • after_find callback will be called whenever Active Record loads a record from the database.
  • after_find is called before after_initialize if both are defined
  • after_touch callback will be called whenever an Active Record object is touched.
  • belongs_to :company, touch: true
  • methods trigger callbacks
  • after_find callback is triggered by the following finder methods
  • after_initialize callback is triggered every time a new object of the class is initialized
  • should be used with caution, however, because important business rules and application logic may be kept in callbacks.
  • As you start registering new callbacks for your models, they will be queued for execution
  • The whole callback chain is wrapped in a transaction
  • Callbacks work through model relationships, and can even be defined by them.
  • As with validations, we can also make the calling of a callback method conditional on the satisfaction of a given predicate
  • When using the :if option, the callback won't be executed if the predicate method returns false; when using the :unless option, the callback won't be executed if the predicate method returns true.
  • with a Symbol
  • with a String
  • with a Proc
  • using eval and hence needs to contain valid Ruby code.
  • mix both :if and :unless in the same callback declaration
  • needed to instantiate a new PictureFileCallbacks object, since we declared our callback as an instance method.
  • Active Record makes it possible to create classes that encapsulate the callback methods, so it becomes very easy to reuse them.
  • won't be necessary to instantiate
  • after_commit
  • after_rollback
  • very similar to the after_save callback except that they don't execute until after database changes have either been committed or rolled back
  • delete_picture_file_from_disk
  • after_commit
  • If anything raises an exception after the after_destroy callback is called and the transaction rolls back, the file will have been deleted and the model will be left in an inconsistent state
    • 張 旭
       
      刪除檔案這種動作,要在資料庫的變動正確執行完成之後。
  • don't supply the :on option the callback will fire for every action.
  • The after_commit and after_rollback callbacks are guaranteed to be called for all models created, updated, or destroyed within a transaction block.
張 旭

elabs/pundit: Minimal authorization through OO design and pure Ruby classes - 0 views

  • The class implements some kind of query method
  • Pundit will call the current_user method to retrieve what to send into this argumen
  • put these classes in app/policies
  • ...49 more annotations...
  • in leveraging regular Ruby classes and object oriented design patterns to build a simple, robust and scaleable authorization system
  • map to the name of a particular controller action
  • In the generated ApplicationPolicy, the model object is called record.
  • record
  • authorize
  • authorize would have done something like this: raise "not authorized" unless PostPolicy.new(current_user, @post).update?
  • pass a second argument to authorize if the name of the permission you want to check doesn't match the action name.
  • you can chain it
  • authorize returns the object passed to it
  • the policy method in both the view and controller.
  • have some kind of view listing records which a particular user has access to
  • ActiveRecord::Relation
  • Instances of this class respond to the method resolve, which should return some kind of result which can be iterated over.
  • scope.where(published: true)
    • 張 旭
       
      我想大概的意思就是:如果是 admin 可以看到全部 post,如果不是只能看到 published = true 的 post
  • use this class from your controller via the policy_scope method:
  • PostPolicy::Scope.new(current_user, Post).resolve
  • policy_scope(@user.posts).each
  • This method will raise an exception if authorize has not yet been called.
  • verify_policy_scoped to your controller. This will raise an exception in the vein of verify_authorized. However, it tracks if policy_scope is used instead of authorize
  • need to conditionally bypass verification, you can use skip_authorization
  • skip_policy_scope
  • Having a mechanism that ensures authorization happens allows developers to thoroughly test authorization scenarios as units on the policy objects themselves.
  • Pundit doesn't do anything you couldn't have easily done yourself. It's a very small library, it just provides a few neat helpers.
  • all of the policy and scope classes are just plain Ruby classes
  • rails g pundit:policy post
  • define a filter that redirects unauthenticated users to the login page
  • fail more gracefully
  • raise Pundit::NotAuthorizedError, "must be logged in" unless user
  • having rails handle them as a 403 error and serving a 403 error page.
  • config.action_dispatch.rescue_responses["Pundit::NotAuthorizedError"] = :forbidden
  • with I18n to generate error messages
  • retrieve a policy for a record outside the controller or view
  • define a method in your controller called pundit_user
  • Pundit strongly encourages you to model your application in such a way that the only context you need for authorization is a user object and a domain model that you want to check authorization for.
  • Pundit does not allow you to pass additional arguments to policies
  • authorization is dependent on IP address in addition to the authenticated user
  • create a special class which wraps up both user and IP and passes it to the policy.
  • set up a permitted_attributes method in your policy
  • policy(@post).permitted_attributes
  • permitted_attributes(@post)
  • Pundit provides a convenient helper method
  • permit different attributes based on the current action,
  • If you have defined an action-specific method on your policy for the current action, the permitted_attributes helper will call it instead of calling permitted_attributes on your controller
  • If you don't have an instance for the first argument to authorize, then you can pass the class
  • restart the Rails server
  • Given there is a policy without a corresponding model / ruby class, you can retrieve it by passing a symbol
  • after_action :verify_authorized
  • It is not some kind of failsafe mechanism or authorization mechanism.
  • Pundit will work just fine without using verify_authorized and verify_policy_scoped
  •  
    "Minimal authorization through OO design and pure Ruby classes"
張 旭

The Exhaustive Guide to Rails Time Zones - Alexander Danilenko - 0 views

  • you can use "wrong" methods in development and fairly often get valid results. But then you'll face with unexpected problems on production.
  • Ruby provides two classes to manage time: Time and DateTime
  • that's in Ruby! When it comes to Rails things get a bit more complicated
  • ...15 more annotations...
  • Rails gives your ability to configure application time zone.
  • we have 3 (!) different time zones in our application: system time, application time and database time.
  • DateTime.now and Time.now both give you the time in system time zone
  • Ruby standard library methods that know nothing about Rails time zone configuration
  • It's not Rails responsible for adding time zone, but ActiveSupport
  • switch from Time.now to Time.zone.now
  • Time.zone.now
  • no need to use it explicitly as there is shorter and more clear option.
  • Time.zone.today
  • Time.zone.local
  • Time.zone.at
  • Time.zone.parse
  • DateTime.strptime(str, "%Y-%m-%d %H:%M %Z").in_time_zone
  • always keep in mind that when you build time or date object you should respect current time zone.
  • use Time.zone instead of Time, Date or DateTime
張 旭

一位开发者的 Linux 容器之旅-技术 ◆ 学习|Linux.中国-开源社区 - 1 views

  • 容器是一个 Linux 进程,Linux 认为它只是一个运行中的进程。该进程只知道它被告知的东西。
  • 容器进程也分配了它自己的 IP 地址。
  • 在容器化方面,容器进程有它自己的 IP 地址。一旦给予了一个 IP 地址,该进程就是宿主网络中可识别的资源
  • ...20 more annotations...
  • 使容器 IP 映射到主机中能访问公网的 IP 地址。建立了该映射,无论出于什么意图和目的,容器就是网络上一个可访问的独立机器,从概念上类似于虚拟机。
  • 容器是拥有不同 IP 地址从而使其成为网络上可识别的独立 Linux 进程
  • CPU、内存和存储空间的分配是动态的,和典型虚拟机的静态方式不同。所有这些资源的共享都由容器管理器来管理。
  • 容器能非常快速地启动
  • 托管容器的计算机运行着被剥离的只剩下主要部分的某个 Linux 版本。
  • 操作系统被所有容器所共享,减少了容器足迹的重复和冗余。每个容器只包括该容器特有的部分
  • 层是一个容器镜像
  • 一个容器组件被称为层(layer)
  • 容器的各种功能都由一个称为容器管理器(container manager)的软件控制
  • 流行的容器管理器是 Docker 和 Rocket
  • 镜像存储在注册库(registry)中,注册库通过网络访问
  • 镜像代表了你的容器需要完成其工作的容器模板
  • 应用程序所需镜像的容器配置文件
  • 每个容器有一个独立的 IP 地址。因此,能把它放到负载均衡器后面。将容器放到负载均衡器后面,这就上升了一个层面。
  • Deis 的容器配置技术
  • 可以部署一个或多个容器镜像到主机上的负载均衡器下
  • 每次添加实例到环境中时,你不需要手动配置负载均衡器以便接受你的容器镜像。你可以使用服务发现技术让容器告知均衡器它可用。
  • 类似 CoreOS、RHEL Atomic、和 Ubuntu 的 Snappy 宿主操作系统
  • 类似 Docker 和 Rocket 的容器管理技术结合起来
  • 类似 Deis 这样的配置技术使容器创建和部署变得更加简单
crazylion lee

flood-io/ruby-jmeter: A Ruby based DSL for building JMeter test plans - 0 views

  •  
    "A Ruby based DSL for building JMeter test plans"
張 旭

ruby-grape/grape: An opinionated framework for creating REST-like APIs in Ruby. - 0 views

shared by 張 旭 on 17 Dec 16 - No Cached
  • Grape is a REST-like API framework for Ruby.
  • designed to run on Rack or complement existing web application frameworks such as Rails and Sinatra by providing a simple DSL to easily develop RESTful APIs
  • Grape APIs are Rack applications that are created by subclassing Grape::API
  • ...54 more annotations...
  • Rails expects a subdirectory that matches the name of the Ruby module and a file name that matches the name of the class
  • mount multiple API implementations inside another one
  • mount on a path, which is similar to using prefix inside the mounted API itself.
  • four strategies in which clients can reach your API's endpoints: :path, :header, :accept_version_header and :param
  • clients should pass the desired version as a request parameter, either in the URL query string or in the request body.
  • clients should pass the desired version in the HTTP Accept head
  • clients should pass the desired version in the UR
  • clients should pass the desired version in the HTTP Accept-Version header.
  • add a description to API methods and namespaces
  • Request parameters are available through the params hash object
  • Parameters are automatically populated from the request body on POST and PUT
  • route string parameters will have precedence.
  • Grape allows you to access only the parameters that have been declared by your params block
  • By default declared(params) includes parameters that have nil values
  • all valid types
  • type: File
  • JSON objects and arrays of objects are accepted equally
  • any class can be used as a type so long as an explicit coercion method is supplied
  • As a special case, variant-member-type collections may also be declared, by passing a Set or Array with more than one member to type
  • Parameters can be nested using group or by calling requires or optional with a block
  • relevant if another parameter is given
  • Parameters options can be grouped
  • allow_blank can be combined with both requires and optional
  • Parameters can be restricted to a specific set of values
  • Parameters can be restricted to match a specific regular expression
  • Never define mutually exclusive sets with any required params
  • Namespaces allow parameter definitions and apply to every method within the namespace
  • define a route parameter as a namespace using route_param
  • create custom validation that use request to validate the attribute
  • rescue a Grape::Exceptions::ValidationErrors and respond with a custom response or turn the response into well-formatted JSON for a JSON API that separates individual parameters and the corresponding error messages
  • custom validation messages
  • Request headers are available through the headers helper or from env in their original form
  • define requirements for your named route parameters using regular expressions on namespace or endpoint
  • route will match only if all requirements are met
  • mix in a module
  • define reusable params
  • using cookies method
  • a 201 for POST-Requests
  • 204 for DELETE-Requests
  • 200 status code for all other Requests
  • use status to query and set the actual HTTP Status Code
  • raising errors with error!
  • It is very crucial to define this endpoint at the very end of your API, as it literally accepts every request.
  • rescue_from will rescue the exceptions listed and all their subclasses.
  • Grape::API provides a logger method which by default will return an instance of the Logger class from Ruby's standard library.
  • Grape supports a range of ways to present your data
  • Grape has built-in Basic and Digest authentication (the given block is executed in the context of the current Endpoint).
  • Authentication applies to the current namespace and any children, but not parents.
  • Blocks can be executed before or after every API call, using before, after, before_validation and after_validation
  • Before and after callbacks execute in the following order
  • Grape by default anchors all request paths, which means that the request URL should match from start to end to match
  • The namespace method has a number of aliases, including: group, resource, resources, and segment. Use whichever reads the best for your API.
  • test a Grape API with RSpec by making HTTP requests and examining the response
  • POST JSON data and specify the correct content-type.
crazylion lee

Building a CLI in Ruby with GLI | Leigh Halliday - 0 views

  •  
    "Building a CLI in Ruby with GLI"
crazylion lee

Awesome Ruby | LibHunt - 1 views

shared by crazylion lee on 17 Apr 16 - No Cached
  •  
    "A collection of awesome Ruby libraries, tools, frameworks and software "
crazylion lee

github/scientist: A Ruby library for carefully refactoring critical paths. - 0 views

  •  
    " A Ruby library for carefully refactoring critical paths."
crazylion lee

mbj/mutant: Mutation testing for Ruby - 0 views

  •  
    "Mutation testing for Ruby"
crazylion lee

westonganger/spreadsheet_architect: SpreadsheetArchitect lets you turn any activerecord... - 1 views

  •  
    "SpreadsheetArchitect lets you turn any activerecord relation or ruby object collection into a XLSX, ODS, or CSV spreadsheet"
張 旭

Understanding Ruby Blocks, Procs and Lambdas - Robert Sosinski - 0 views

  • Ruby has four different ways of using closures
  • The code block interacts with a variable
  • collect! will use the code provided within the block on each element in the array
  • ...10 more annotations...
  • do not need to specify the name of blocks within your methods
  • use the yield keyword. Calling this keyword will execute the code within the block provided to the method
  • A block is just a Proc!
  • saving reusable code as an object itself. This reusable code is called a Proc (short for procedure)
  • The only difference between blocks and Procs is that a block is a Proc that cannot be saved, and as such, is a one time use solution
  • a bang at the end
  • That value is now available to the block and returned by the yield call
  • The block has the number available (also called n)
  • a flexible way to interact with our method
  • an ampersand argument
張 旭

The Rails Command Line - Ruby on Rails Guides - 0 views

  • rake --tasks
  • Think of destroy as the opposite of generate.
  • runner runs Ruby code in the context of Rails non-interactively
  • ...28 more annotations...
  • rails dbconsole figures out which database you're using and drops you into whichever command line interface you would use with it
  • The console command lets you interact with your Rails application from the command line. On the underside, rails console uses IRB
  • rake about gives information about version numbers for Ruby, RubyGems, Rails, the Rails subcomponents, your application's folder, the current Rails environment name, your app's database adapter, and schema version
  • You can precompile the assets in app/assets using rake assets:precompile and remove those compiled assets using rake assets:clean.
  • rake db:version is useful when troubleshooting
  • The doc: namespace has the tools to generate documentation for your app, API documentation, guides.
  • rake notes will search through your code for comments beginning with FIXME, OPTIMIZE or TODO.
  • You can also use custom annotations in your code and list them using rake notes:custom by specifying the annotation using an environment variable ANNOTATION.
  • rake routes will list all of your defined routes, which is useful for tracking down routing problems in your app, or giving you a good overview of the URLs in an app you're trying to get familiar with.
  • rake secret will give you a pseudo-random key to use for your session secret.
  • Custom rake tasks have a .rake extension and are placed in Rails.root/lib/tasks.
  • rails new . --git --database=postgresql
  • All commands can run with -h or --help to list more information
  • The rails server command launches a small web server named WEBrick which comes bundled with Ruby
  • rails server -e production -p 4000
  • You can run a server as a daemon by passing a -d option
  • The rails generate command uses templates to create a whole lot of things.
  • Using generators will save you a large amount of time by writing boilerplate code, code that is necessary for the app to work.
  • All Rails console utilities have help text.
  • generate controller ControllerName action1 action2.
  • With a normal, plain-old Rails application, your URLs will generally follow the pattern of http://(host)/(controller)/(action), and a URL like http://(host)/(controller) will hit the index action of that controller.
  • A scaffold in Rails is a full set of model, database migration for that model, controller to manipulate it, views to view and manipulate the data, and a test suite for each of the above.
  • Unit tests are code that tests and makes assertions about code.
  • Unit tests are your friend.
  • rails console --sandbox
  • rails db
  • Each task has a description, and should help you find the thing you need.
  • rake tmp:clear clears all the three: cache, sessions and sockets.
crazylion lee

janko-m/shrine: File upload toolkit for Ruby - 0 views

  •  
    "File upload toolkit for Ruby http://shrinerb.com"
張 旭

Active Record Migrations - Ruby on Rails Guides - 0 views

    • 張 旭
       
       跟 belongs_to 與 has_many 設定對應的 Migrattion
    • 張 旭
       
      has_and_belongs_to_many 的對應?
  • add_column and remove_column
  • ...114 more annotations...
  • allowing your schema and changes to be database independent.
  • each migration as being a new 'version' of the database
  • each migration modifies it to add or remove tables, columns, or entries
  • Active Record will also update your db/schema.rb file to match the up-to-date structure of your database.
  • A primary key column called id will also be added implicitly, as it's the default primary key for all Active Record models
  • roll this migration back, it will remove the table
  • timestamps macro adds two columns, created_at and updated_at
  • On databases that support transactions with statements that change the schema, migrations are wrapped in a transaction
  • reversible
  • use up and down instead of change
  • Migrations are stored as files in the db/migrate directory, one for each migration class.
  • a UTC timestamp identifying
  • Rails uses this timestamp to determine which migration should be run and in what order
  • "AddXXXToYYY" or "RemoveXXXFromYYY"
  • use a Ruby DSL
  • column type as references
  • part_number:string:index
  • a migration to remove a column
  • "CreateXXX"
  • change_column_null
  • AddUserRefToProducts
  • :references
  • produce join tables if JoinTable is part of the name
  • CreateJoinTable
  • The model and scaffold generators will create migrations appropriate for adding a new model.
  • enclosed by curly braces and follow the field type
  • create_table
  • By default, create_table will create a primary key called id
  • add an index on the new column
  • when using MySQL, the default is ENGINE=InnoDB
  • create_join_table creates an HABTM (has and belongs to many) join table
  • To customize the name of the table, provide a :table_name option:
  • create_join_table also accepts a block
  • change_table, used for changing existing tables
  • remove
  • rename
  • add_column
  • change_column
  • remove_column
  • change_column_default
  • place an SQL fragment in the :options option.
  • limit
  • precision
  • scale
  • polymorphic
  • default
  • index
  • add_foreign_key
  • Active Record only supports single column foreign keys.
  • use the old style of migration using up and down methods instead of the change method.
  • .connection.execute
  • change_table is also reversible, as long as the block does not call change, change_default or remove.
  • remove_column is reversible if you supply the column type as the third argument
  • Complex migrations may require processing that Active Record doesn't know how to reverse
  • reversible
  • Using reversible will ensure that the instructions are executed in the right order too.
  • add_column add_foreign_key add_index add_reference add_timestamps change_column_default (must supply a :from and :to option) change_column_null create_join_table create_table disable_extension drop_join_table drop_table (must supply a block) enable_extension remove_column (must supply a type) remove_foreign_key (must supply a second table) remove_index remove_reference remove_timestamps rename_column rename_index rename_table
  • :column_options option
  • have the option :null set to false by default
  • By default, the name of the join table comes from the union of the first two arguments provided to create_join_table
  • in alphabetical order
  • change_column command is irreversible.
    • 張 旭
       
      關聯物在前,被關聯物在後。 A 關聯到 B
  • If the column names can not be derived from the table names, you can use the :column and :primary_key options.
  • figure out the column name
  • foreign key for a specific column
  • foreign key by name
    • 張 旭
       
      不懂 column 跟 name 的用法差異,基本上一樣。
  • Active Record knows how to reverse the migration automatically
    • 張 旭
       
      使用內建的 method,Rails 比較容易自動 rollback
    • 張 旭
       
      除了幾個特殊的 change_ 跟 remove_
  • should use reversible or write the up and down methods instead of using the change method
  • If your migration is irreversible, you should raise ActiveRecord::IrreversibleMigration from your down method.
  • DontUseConstraintForZipcodeValidationMigration
  • rails db:migrate
  • the db:migrate task also invokes the db:schema:dump task, which will update your db/schema.rb file to match the structure of your database.
  • specify a target version
  • all migrations up to and including 20080906120000
  • run the down method on all the migrations down to, but not including, 20080906120000
  • rails db:rollback
  • db:migrate:redo task is a shortcut for doing a rollback and then migrating back up again
    • 張 旭
       
      舊版的還是 rake!
  • STEP parameter
  • db:setup task will create the database, load the schema and initialize it with the seed data
  • db:reset task will drop the database and set it up again. This is functionally equivalent to rails db:drop db:setup.
  • run a specific migration up or down, the db:migrate:up and db:migrate:down
  • the RAILS_ENV environment variable
  • db:migrate VERBOSE=false will suppress all output.
  • If you have already run the migration, then you cannot just edit the migration and run the migration again: Rails thinks it has already run the migration and so will do nothing when you run rails db:migrate.
  • must rollback the migration (for example with bin/rails db:rollback), edit your migration and then run rails db:migrate to run the corrected version.
  • editing existing migrations is not a good idea.
  • should write a new migration that performs the changes you require
  • revert method can be helpful when writing a new migration to undo previous migrations in whole or in part
  • require_relative
  • revert
  • They are not designed to be edited, they just represent the current state of the database.
  • Schema Files for
  • Schema files are also useful if you want a quick look at what attributes an Active Record object has
  • annotate_models gem automatically adds and updates comments at the top of each model summarizing the schema if you desire that functionality.
  • database-independent
  • multiple databases
  • db/schema.rb cannot express database specific items such as triggers, stored procedures or check constraints
  • you can execute custom SQL statements, the schema dumper cannot reconstitute those statements from the database
  • db:structure:dump
    • 張 旭
       
      資料庫種類不相依的 schema 付出的代價就是有些特殊的資料庫特性無法描述出來,例如 trigger;如果有在 migration 寫 SQL 的,簡單說 schema dumper 這邊就要設定成 :sql 而不是預設的 :ruby
  • set in config/application.rb by the config.active_record.schema_format setting, which may be either :sql or :ruby.
  • check them into source control.
  • db/schema.rb contains the current version number of the database
  • Validations such as validates :foreign_key, uniqueness: true are one way in which models can enforce data integrity
  • The :dependent option on associations allows models to automatically destroy child objects when the parent is destroyed.
  • Migrations can also be used to add or modify data
  • Initial
  • To add initial data after a database is created, Rails has a built-in 'seeds' feature that makes the process quick and easy.
  • db/seeds.rb
  • rails db:seed
crazylion lee

GitHub - Mange/roadie: Making HTML emails comfortable for the Ruby rockstars - 0 views

  •  
    "Making HTML emails comfortable for the Ruby rockstars"
張 旭

Ruby and AOP: Decouple your code even more - Arkency Blog - 0 views

  • Dark Parts in our apps - persistence, networking, logging, notifications… these parts are scattered in our code
  • aspect-oriented programming!
  • components are parts we can easily encapsulate into some kind of code abstraction - a methods, objects or procedures.
  • ...16 more annotations...
  • application’s logic is a great example of a component
  • Aspects cross-cut our application - when we use some kind of persistence (e.g. a database) or network communication (such as ZMQ sockets) our components need to know about it.
  • Aspect-oriented programming aims to get rid of cross-cuts by separating aspect code from component code using injections of our aspects in certain join points in our component code.
  • It’s responsible for pushing snippets scenario
  • SRP-conformant object
  • the join points in Ruby
  • advice
    • 張 旭
       
      AOP 裡面的術語
  • In most cases after and before advice are sufficient.
  • what does it mean to “evaluate code around” something? In our case it means: Don’t run this method. Take it and push to my advice as an argument and evaluate this advice
  • to provide a join point
  • You’ll often see empty methods in code written in AOP paradigm
  • provide aspect code to link with our use case
  • use case is a pure domain object, without even knowing it’s connected with some kind of persistence and logging layer.
  • Aspect-oriented programming is fixing the problem with polluting pure logic objects with technical context of our applications.
  • we treat our glues as a configuration part, not the logic part of our apps.
  • Glues should not contain any logic at all
1 - 20 of 99 Next › Last »
Showing 20 items per page