Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[1685] Move from Metasearch to Ransack #1979

Closed
wants to merge 4 commits into from
Closed

Conversation

seanlinsley
Copy link
Contributor

This PR is for #1685, and is a continuation of the work @pavelbrylov did in #1811.

BTW

  • this is on @gregbell's repo
  • be sure to add an extra set of quote marks when referencing this branch name: '"metasearch->ransack"'

Using this with Rails 4

This doesn't currently work 100% with RaIls 4, but it's close. You need to specify these gems:

gem 'activeadmin',         github: 'gregbell/active_admin', branch: 'rails4'
gem 'ransack',             github: 'ernie/ransack',         branch: 'rails-4'
gem 'inherited_resources', github: 'josevalim/inherited_resources'
gem 'sass-rails', '~> 4.0.0.rc2'

@seanlinsley seanlinsley mentioned this pull request Mar 8, 2013
@macfanatic
Copy link
Contributor

@daxter - thanks for the tip on the branch name.

@jackdempsey
Copy link

how's this going Daxter? I'm creating a new rails 4 app and it's hard to not have my trusty AA at the ready. Is there much more work to do here? After this, do you have any idea how much more work is needed to get to rails 4?

cheers

@seanlinsley
Copy link
Contributor Author

@jackdempsey I haven't tried working on this for a while now, but it shouldn't take too much longer.

As far as I'm aware, meta_search is the only thing in the way of Rails 4 compatibility.

@jasperkennis
Copy link

There's this fork that might be a good starting point to solving this.

@jackdempsey
Copy link

thx jasper. I'm somewhat inclined to put some $ behind this desire using https://www.bountysource.com
I have zero free time to assist but I'd pitch in $50 to get AA working on Rails 4. Any takers?

@seanlinsley
Copy link
Contributor Author

Haha, I was going to do it nonetheless. Hence this PR. :)

@jackdempsey
Copy link

:-) Do you have any sense how hard it'll be to switch to Ransack? If it's a
small amount of work to get working with meta_search, that makes sense. If
that's going to be a lot of work, seems smart to consider the switch to
Ransack?

Course switching multiple things at the same time (rails 4 AND ransack)
never turns out as smart as it feelas at the beginning :-)

On Tue, Apr 2, 2013 at 9:33 AM, Sean Ian Linsley
notifications@github.comwrote:

Haha, I was going to do it nonetheless. Hence this PR. :)


Reply to this email directly or view it on GitHubhttps://github.com//pull/1979#issuecomment-15786636
.

@seanlinsley
Copy link
Contributor Author

It's mostly plug-and-play for Ransack, but there's one unresolved issue (a la #1811) that needs to be resolved.

I can't be sure about Rails 4, but Ransack should be integrated this week.

@seanlinsley
Copy link
Contributor Author

Did that really just happen?

Using worker: bluebox-linux-7.worker.travis-ci.org:travis-linux-1

$ export RAILS=3.2.13
travis_fold:start:git.1
$ git clone --depth=50 --branch=metasearch->ransack git://github.com/gregbell/active_admin.git gregbell/active_admin
warning: Could not find remote branch metasearch- to clone.
fatal: Remote branch metasearch- not found in upstream origin

The command "git clone --depth=50 --branch=metasearch- git://github.com/gregbell/active_admin.git gregbell/active_admin > ransack" failed and exited with 128 during checkout.

Your build has been stopped.

Oh man. That's what I get for being a nonconformist.

@seanlinsley
Copy link
Contributor Author

Everything is working now, except the index page scenario for AA Comments. As in:

ActiveAdmin.register ActiveAdmin::Comment, as: 'Comment' do
  # ...
end

The basic problem is the polymorphic association between comments and your models are getting corrupted (not sure where it's happening). I'm attempting to re-use the Issue that @pavelbrylov opened earlier: activerecord-hackery/ransack#173

@lupinglade
Copy link
Contributor

I've got this branch added to the Gemfile, but bundle returns:

Bundler could not find compatible versions for gem "activerecord":
  In Gemfile:
    activeadmin (>= 0) ruby depends on
      activerecord (~> 3.0) ruby

    rails (= 4.0.0.beta1) ruby depends on
      activerecord (4.0.0.beta1)

Any ideas?

@seanlinsley
Copy link
Contributor Author

@lupinglade looks like you edited your comment after the fact. Earlier you were asking how to get Bundler to recognize the unusual branch name, and just FYI you can get around that by specifying a commit ID instead.

How exactly do you have it set up now? I could see you getting that error if you're using a local copy of Active Admin instead of using Bundler.

@lupinglade
Copy link
Contributor

I have it wrapped in escaped quotes and that gets the right branch, but running bundle install gives the error above. I've also tried separately checking out the branch and running bundle on the source and the same error occurs. This is with rails 4.0.0.beta1, rvm head, ruby 2.0.0

Here's what I have in the Gemfile:

gem 'activeadmin', github: "gregbell/active_admin", branch: ""metasearch->ransack""

I've tried with the commit ID and the same thing happens (bundle error as above).

@lupinglade
Copy link
Contributor

I don't understand where activeadmin >= 0 depends on activerecord (~> 3.0)...

I've looked at the value of the detect_rails_version method and it returns 4.0.0.beta1 properly.

It seems its a problem with the ransack gem and maybe some other dependencies still being stuck with rails 3?

@seanlinsley
Copy link
Contributor Author

Bundler is being a bit inaccurate in its error message. The real problem is that Ransack specifies Rails 3.x

    ransack (0.7.2)
      actionpack (~> 3.0)
      activerecord (~> 3.0)
      polyamorous (~> 0.5.0)

There's an open PR to fix this. Let me know if it works for you.

gem 'ransack', github: 'avit/ransack', branch: 'rails4-dependencies'

@lupinglade
Copy link
Contributor

That fixed it, thank you!

@lupinglade
Copy link
Contributor

Strange, now I am getting another error:

>> rails generate active_admin:install

/Users/lupinglade/.rvm/gems/ruby-2.0.0-p0@rails-4.0.0.beta1/bundler/gems/active_admin-d2b9840832f4/lib/active_admin/sass/helpers.rb:9:in `<module:Helpers>': uninitialized constant Sass::Rails::Helpers (NameError)
    from /Users/lupinglade/.rvm/gems/ruby-2.0.0-p0@rails-4.0.0.beta1/bundler/gems/active_admin-d2b9840832f4/lib/active_admin/sass/helpers.rb:7:in `<module:Sass>'
    from /Users/lupinglade/.rvm/gems/ruby-2.0.0-p0@rails-4.0.0.beta1/bundler/gems/active_admin-d2b9840832f4/lib/active_admin/sass/helpers.rb:6:in `<module:ActiveAdmin>'
    from /Users/lupinglade/.rvm/gems/ruby-2.0.0-p0@rails-4.0.0.beta1/bundler/gems/active_admin-d2b9840832f4/lib/active_admin/sass/helpers.rb:5:in `<top (required)>'
    from /Users/lupinglade/.rvm/gems/ruby-2.0.0-p0@rails-4.0.0.beta1/bundler/gems/active_admin-d2b9840832f4/lib/active_admin.rb:12:in `<top (required)>'
    from /Users/lupinglade/.rvm/gems/ruby-2.0.0-p0@rails-4.0.0.beta1/bundler/gems/active_admin-d2b9840832f4/lib/activeadmin.rb:1:in `<top (required)>'
    from /Users/lupinglade/.rvm/gems/ruby-2.0.0-p0@rails-4.0.0.beta1/gems/bundler-1.3.5/lib/bundler/runtime.rb:72:in `require'
    from /Users/lupinglade/.rvm/gems/ruby-2.0.0-p0@rails-4.0.0.beta1/gems/bundler-1.3.5/lib/bundler/runtime.rb:72:in `block (2 levels) in require'
    from /Users/lupinglade/.rvm/gems/ruby-2.0.0-p0@rails-4.0.0.beta1/gems/bundler-1.3.5/lib/bundler/runtime.rb:70:in `each'
    from /Users/lupinglade/.rvm/gems/ruby-2.0.0-p0@rails-4.0.0.beta1/gems/bundler-1.3.5/lib/bundler/runtime.rb:70:in `block in require'
    from /Users/lupinglade/.rvm/gems/ruby-2.0.0-p0@rails-4.0.0.beta1/gems/bundler-1.3.5/lib/bundler/runtime.rb:59:in `each'
    from /Users/lupinglade/.rvm/gems/ruby-2.0.0-p0@rails-4.0.0.beta1/gems/bundler-1.3.5/lib/bundler/runtime.rb:59:in `require'
    from /Users/lupinglade/.rvm/gems/ruby-2.0.0-p0@rails-4.0.0.beta1/gems/bundler-1.3.5/lib/bundler.rb:132:in `require'
    from /Users/lupinglade/Documents/Aebol/Projects/aebol/config/application.rb:6:in `<top (required)>'
    from /Users/lupinglade/.rvm/gems/ruby-2.0.0-p0@rails-4.0.0.beta1/gems/railties-4.0.0.beta1/lib/rails/commands.rb:44:in `require'
    from /Users/lupinglade/.rvm/gems/ruby-2.0.0-p0@rails-4.0.0.beta1/gems/railties-4.0.0.beta1/lib/rails/commands.rb:44:in `<top (required)>'
    from bin/rails:4:in `require'
    from bin/rails:4:in `<main>'

@lupinglade
Copy link
Contributor

I could get past it by marking out that include ::Sass::Rails::Helpers, but then the next error is:

`attr_accessible` is extracted out of Rails into a gem. Please use new recommended protection model for params(strong_parameters) or add `protected_attributes` to your Gemfile to use old one.

Even if I add protected_attributes gem to the Gemfile (and bundle install), that same error comes up.

How do you have this working? :-/

@lupinglade
Copy link
Contributor

Nevermind, I got it. You're doing the migration on rails 3 and I'm testing on rails 4 :)

@seanlinsley
Copy link
Contributor Author

How exactly did you get around that error?

@lupinglade
Copy link
Contributor

Do you mean the one regarding attr_accessible? I haven't yet, but I am looking into it.

@lupinglade
Copy link
Contributor

Any idea why the Sass module is uninitialized? If I can fix that maybe I can get the rest of it working on rails 4.

@lupinglade
Copy link
Contributor

To fix that attr_accessible error, we need to remove the attr_accessible definitions in comment.rb and then add a strong parameters definition to the controller responsible for the comments. Something along the lines of:

private
def comment_params
  params.require(:resource).permit(:resource_id, :resource_type, :body, :namespace)
end

Instead of this in comment.rb

attr_accessible :resource, :resource_id, :resource_type, :body, :namespace

Then the create implementation should be something like:

def create
  @comment = Comment.new(comment_params)
  # ...
end

Just not sure where to place this since it looks like the controller is dynamically generated. I am thinking lib/active_admin/comments.rb?

@seanlinsley
Copy link
Contributor Author

Is there no way to support either or, depending on whether the app is using Rails 4?

@lupinglade
Copy link
Contributor

Well, requiring the 'protected_attributes' gem should work at least until rails 5. It did not seem to work if I add it to the project Gemfile, so I think it needs to be done in active_admin itself.

Its the only place that its used though from what I can tell, so it might be worthwhile to switch to strong_parameters dynamically based on what version of rails active_admin is running on?

Not sure which is better.

@lupinglade
Copy link
Contributor

If we can get the Sass issue fixed, I can check to see what other things we might run into on Rails 4.

@seanlinsley
Copy link
Contributor Author

@lupinglade could you please discuss Rails 4 compatibility in #1963? This really isn't the place for it.

@seanlinsley
Copy link
Contributor Author

Could you elaborate? If you specify this branch in your Gemfile, it should just work.

gem 'activeadmin', github: 'gregbell/active_admin', branch: '"metasearch->ransack"'

If you're trying to use Rails 4, you should check out #1963.

@grumpit
Copy link

grumpit commented May 29, 2013

Ah, I had missed putting the double quotes inside the single. That said, I still get the following:

$ bundle
Updating git://github.com/gregbell/active_admin.git
Fetching gem metadata from https://rubygems.org/..........
Fetching gem metadata from https://rubygems.org/..
Resolving dependencies...
Bundler could not find compatible versions for gem "activerecord":
  In Gemfile:
    activeadmin (>= 0) ruby depends on
      activerecord (~> 3.0) ruby

    rails (= 4.0.0.beta1) ruby depends on
      activerecord (4.0.0.beta1)

Yeah, obv using rails 4 - thought this had been merged in with the other

@seanlinsley
Copy link
Contributor Author

Last time I checked no one's paying me to do this, so you shouldn't expect me to have all the answers.

As it so happens @lupinglade already mentioned that problem and I ran down the solution.

Though that appears to be out of date

@grumpit
Copy link

grumpit commented May 29, 2013

Chill, dude, I obviously wasn't clear - when I said "thought this had been merged in with the other" I was meaning that I had misunderstood, thinking the two threads/pull reqs were more related than they were.

Using the other thread you referenced, I got it to work by doing the following:

gem 'devise',              github: 'plataformatec/devise',     branch: 'rails4'
gem 'responders',          github: 'plataformatec/responders'
gem 'inherited_resources', github: 'josevalim/inherited_resources'
gem 'ransack',             github: 'ernie/ransack',            branch: 'rails-4'
# gem 'protected_attributes' # only until after installing active admin using generator
gem 'activeadmin',         github: 'akashkamboj/active_admin', branch: 'rails4'

@seanlinsley
Copy link
Contributor Author

Yeah my bad. I was getting annoyed because the answer was right there. But I guess if I happened across long threads like these I wouldn't actually read them unless absolutely necessary.

I updated the description text for this PR to be more useful.

@seanlinsley
Copy link
Contributor Author

Huh. Apparently with Ransack you can change between _matches and _cont so you can directly use the SQL LIKE percent signs, placing them where you want.

-- User.search(username_cont: 'jim%').result.count
SELECT COUNT(*) FROM "users" WHERE ("users"."username" LIKE '%jim\%%')
-- User.search(username_cont: 'jim').result.count
SELECT COUNT(*) FROM "users" WHERE ("users"."username" LIKE '%jim%')
-- User.search(username_matches: 'jim%').result.count
SELECT COUNT(*) FROM "users" WHERE ("users"."username" LIKE 'jim%')

@seanlinsley
Copy link
Contributor Author

I'm currently remaking this PR to catch it up with master.

I should have it working today, but for now you can always refer to the old commit hash: d3aa5a2

@seanlinsley
Copy link
Contributor Author

I have no idea why Travis won't correctly resolve the Bundler dependencies for Rails 4:

Bundler could not find compatible versions for gem "actionpack":
  In Gemfile:
    activeadmin (>= 0) ruby depends on
      actionpack (~> 3.0.0.rc2) ruby
    rails (= 4.0.0.rc2) ruby depends on
      actionpack (4.0.0.rc2)

It works for me locally

@agrobbin
Copy link
Contributor

I ran into this problem because of meta_search still being included in the gemspec.

@seanlinsley
Copy link
Contributor Author

Ahh... of course. I don't know how that escaped me.

nebirhos and others added 4 commits June 20, 2013 16:41
Conflicts:
	activeadmin.gemspec

undoes 1d29474, to apply the full fix
#### Removed outdated version-checking conditions
Modules affected:
+ CSV parser
+ asset registration
+ class reloading in development

#### Removed 99% of our custom class reloader in favor of Rails reloading
Note: I removed the code that purges `app/admin` from Rails' `eager_load_paths`
since there were no bad effects of doing so. Only the code that does this for
Rails' `autoload_paths` seems necessary.

#### Gemspec dependencies updated
+ fastercsv removed
+ coffee-rails added
+ sass replaced by sass-rails
Adds conditionals to the admin user generator, and to the AA Comments
model & controller to handle both Protected Attributes and Strong Paramaters

Also updates dependencies so the test Rails 4 app will at least bundle
Note that while Ransack renames many query methods ("predicates"), this
commit creates aliases for the more plain-english predicates so they
still work as expected.

To see the full list of Ransack predicates, check out
`lib/ransack/constants.rb` in the Ransack source code.

This commit also removes polymorphic foreign types from the default
list of filters for a resource, since Ransack seems to barf on them. We
don't have a good filter UI for them anyway, so it's not a huge issue.
@boontdustie
Copy link

Are there any examples that show how to update the old Metasearch search_method approach for filters
to the new 'ransack' way of doing things? I am currently running into issues getting search filters working.

Specifically, trying to upgrade something like this so that it can work with ransack:

In Active Admin resource:

filter :month, :as => :select, :collection => (1..12)

In model:

scope :month_eq, lambda{ |month| where("strftime('%m', birthday) + 0 = ?", month.to_i) }
search_methods :month_eq

How would one do this with ransack?

Example stolen from: http://stackoverflow.com/a/12045146/2308991

Thanks!

@seanlinsley
Copy link
Contributor Author

The documentation for Ransack is terrible. The best resource is discussions that people have had on the Issue tracker like this: activerecord-hackery/ransack#36

I'll try to write something up for this.

@Fivell
Copy link
Member

Fivell commented Aug 5, 2013

@boontdustie , did you find solution ?

@boontdustie
Copy link

@Fivell - Sorry, no. We ended up just going a different route for the filters that doesn't involve ransack.

@seanlinsley
Copy link
Contributor Author

I just figured it out:

# The scope version
scope :month_eq, lambda{ |month| where("strftime('%m', created_at) + 0 = ?", month.to_i) }
# the Ransack version
ransacker :month, formatter: proc(&:to_i) do |parent|
  Arel::Nodes::SqlLiteral.new "strftime('%m', #{parent.table_name}.created_at) + 0"
end

# So both of these work:
Post.month_eq(8)
Post.search(month_eq: 8).result

# So this AA filter should now work as expected:
filter :month, :as => :select, :collection => (1..12)

It bugs me that this causes code duplication...

UPDATE: Hmm, looks like using that as a filter raises an odd error. The error only happens with equals, not greater or lesser than. See http://stackoverflow.com/questions/12605518 for more info

@Fivell
Copy link
Member

Fivell commented Aug 5, 2013

@daxter , you are right, almost no docs for ransacker....Can't figure out how to rewrite simple module to use with AA and rails4

module CurrencyEqScopes
  def self.included(base)
    base.scope :currency_id_eq, lambda { |currency|
       base.joins(:currency).where("currencies.id = ?", currency)
   }
    base.send :search_methods, :currency_id_eq
  end
end

@seanlinsley
Copy link
Contributor Author

#2326 includes the code from this PR, so I'm closing this.

@seanlinsley
Copy link
Contributor Author

And now #2326 has been merged into master :D

@seanlinsley seanlinsley deleted the metasearch->ransack branch September 25, 2013 01:56
@exAspArk
Copy link

I think you should use filter with predicate like this:

# /app/models/project.rb
class Project < ActiveRecord::Base
  ransacker :month, formatter: proc(&:to_i) do |parent|
    Arel::Nodes::SqlLiteral.new "strftime('%m', #{parent.table_name}.created_at) + 0"
  end
end

# /app/admin/projects.rb
ActiveAdmin.register Project do
  filter :month_eq, as: :select, collection: (1..12)
end

If you run it like filter :month it wiil show you an error: ArgumentError (No valid predicate for month)

@seanlinsley
Copy link
Contributor Author

Is that really all that was needed? xD

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.