brendon / acts_as_list

An ActiveRecord plugin for managing lists.
http://brendon.github.io/acts_as_list/
MIT License
2.04k stars 355 forks source link

Updates documentation with valid string interpolation syntax #249

Closed naveedkakal closed 7 years ago

naveedkakal commented 7 years ago

Bumped into this while copy pasting some code from the docs.

brendon commented 7 years ago

Thanks @naveedkakal :)

brendon commented 7 years ago

Wait a minute, if you use double quotes the interpolation will happen straight away. Normally we don't want this, we want the string to be interpolated in relation to the current record.

Can you double check this for me? Might have to revert this doc.

naveedkakal commented 7 years ago

I think you may be right - let's revert it for now.

naveedkakal commented 7 years ago
define_method :scope_condition do
  eval "%{#{scope}}"
 end

Looks like this is what I missed - i didn't realize it was an eval happening there.

Apologies!

brendon commented 7 years ago

That's all good :)

brendon commented 7 years ago

No worries man, it's a messed up configuration syntax anyway!

naveedkakal commented 7 years ago

Interestingly the thing I was trying to solve for is actually an open issue with the PG::DEADLOCK issues.

For my case what I really needed to do is have some logic around the scoping attribute

acts_as_list scope: '#{plan_id ? "plan_id = \'" + plan_id + "\'": "1=0"}'

I was tinkering with a PR for acts_as_list to also accept a proc as a scope - do you think something like that would be a good idea? My reasons for it were related to another known issue so this may be just be a workaround that doesn't belong as supported functionality.

Any thoughts?

brendon commented 7 years ago

Accepting a proc might be a good idea. Alternatively you can override the scope_condition and scope_changed? methods to do what you want. This is an example:

  def scope_condition
    ['notice_area_id = ? AND ? >= CURDATE()', notice_area_id, end_date]
  end

  # A custom acts_as_list scope requires a custom scoped_changed? method
  def scope_changed?
    changed.include?('notice_area_id') ||
    changed.include?('end_date') && (
      changes['end_date'][0] >= Time.zone.now.beginning_of_day &&
      changes['end_date'][1] < Time.zone.now.beginning_of_day ||
      changes['end_date'][1] >= Time.zone.now.beginning_of_day &&
      changes['end_date'][0] < Time.zone.now.beginning_of_day
    )
  end

I hope that helps :)