
Security News
Follow-up and Clarification on Recent Malicious Ruby Gems Campaign
A clarification on our recent research investigating 60 malicious Ruby gems.
= dm-is-list
DataMapper plugin for creating and organizing lists.
== Installation
=== Stable
Install the dm-is-list gem.
$ (sudo)? gem install dm-is-list
=== Edge
Download or clone dm-is-list from Github[http://github.com/datamapper/dm-is-list/].
$ cd /path/to/dm-is-list
$ rake install # will install dm-is-list
$ password ...
== Getting started
To start using this gem, just require dm-is-list in your app.
require 'dm-core' # must be required first require 'dm-is-list'
Lets say we have a User class, and we want to give users the possibility of having their own todo-lists.
class User include DataMapper::Resource
property :id, Serial
property :name, String
has n, :todos
end
class Todo include DataMapper::Resource
property :id, Serial
property :title, String
property :done, DateTime
belongs_to :user
# here we define that this should be a list, scoped on :user_id
is :list, :scope => :user_id # you may also pass in multiple properties, eg [ :user_id, :title ]
end
Once we have our Users and Lists, we might want to work with...
== Movements of list items
Any list item can be moved around within the same list easily through the #move method.
=== :move( vector )
There are number of convenient vectors that help you move items around within the list.
item = Todo.get(1) other = Todo.get(2)
item.move(:highest) # moves to top of list. item.move(:lowest) # moves to bottom of list. item.move(:top) # moves to top of list. item.move(:bottom) # moves to bottom of list. item.move(:up) # moves one up (:higher and :up is the same) within the scope. item.move(:down) # moves one up (:lower and :down is the same) within the scope. item.move(:to => position) # moves item to a specific position. item.move(:above => other) # moves item above the other item.* item.move(:below => other) # moves item above the other item.*
The list will act as intelligently as possible and keep positions in a logical running order.
=== :move( Integer )
NOTE! VERY IMPORTANT!
If you set the position manually, and then save, the list will NOT reorganize itself.
item.position = 3 # setting position manually item.save # the item will now have position 3, but the list may have two items with the same position.
item.update(:position => 3) # sets the position manually, but does not reorganize the list positions.
You should therefore always use the item.move(N) syntax instead.
item.move(3) # does the same as above, but in one call AND reorganizes the list.
Hold On!
dm-is-list used to work with item.position = 1 type syntax. Why this change?
The main reason behind this change was that the previous version of dm-is-list created a LOT of extra SQL queries in order to support the manual updating of position, and as a result had a quite a few bugs/issues, which have been fixed in this version.
The other reason is that I couldn't work out how to keep the functionality without adding the extra queries. But perhaps you can ?
See "Batch Changing Positions" below for information on how to change the positions on a whole list.
== Movements between scopes
When you move items between scopes, the list will try to work with your intentions.
Move the item from list to new list and add the item to the bottom of that list.
item.user_id # => 1 item.move_to_list(10) # => the scope id ie User.get(10).id
item.user_id # => 10 item.position # => < bottom of the list >
Move the item from list to new list and add at the position given.
item.user_id # => 1 item.move_to_list(10, 2) # => the scope id ie User.get(10).id, position => 2
item.user_id # => 10 item.position # => 2
== Batch Changing Positions
A common scenario when working with lists is the sorting of a whole list via something like JQuery's sortable() functionality.
(Think re-arranging the order of Todo's according to priority or something similar)
=== Optimum scenario
The most SQL query efficient way of changing the positions is:
sort_order = [5,4,3,2,1] # list from AJAX request..
items = Todo.all(:user => @u1) # loads all 5 items in the list
items.each{ |item| item.update(:position => sort_order.index(item.id) + 1) } # remember the +1 since array's are indexed from 0
The above code will result in something like these queries.
Remember! Your sort order list has to be the same length as the found items in the list, or your loop will fail.
=== Wasteful scenario
You can also use this version, but it will create upto 5 times as many SQL queries. :(
sort_order = ['5','4','3','2','1'] # list from AJAX request..
items = Todo.all(:user => @u1) # loads all 5 items in the list
items.each{ |item| item.move(sort_order.index(item.id).to_i + 1) } # remember the +1 since array's are indexed from 0
The above code will result in something like these queries:
As you can see it will also do the job, but will be more expensive.
== RTFM
As I said above, for a better understanding of this gem/plugin, make sure you study the 'dm-is-list/spec/integration/list_spec.rb' tests.
== Errors / Bugs
If something is not behaving intuitively, it is a bug, and should be reported. Report it here: http://datamapper.lighthouseapp.com/
== TODOs
== Note on Patches/Pull Requests
== Copyright
Copyright (c) 2011 Sindre Aarsaether. Released under the MIT License.
See LICENSE for details.
=== Credits
Credit also goes to these contributors[http://github.com/datamapper/dm-is-list/contributors].
FAQs
Unknown package
We found that dm-is-list demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
A clarification on our recent research investigating 60 malicious Ruby gems.
Security News
ESLint now supports parallel linting with a new --concurrency flag, delivering major speed gains and closing a 10-year-old feature request.
Research
/Security News
A malicious Go module posing as an SSH brute forcer exfiltrates stolen credentials to a Telegram bot controlled by a Russian-speaking threat actor.