user2784630
user2784630

Reputation: 806

How to create a model scope with Geocoder?

I have the following models, User, Dad, Mom, Follow and Kid.

class User
 has_many :kids
 has_many :follows
 geocoded_by :address
end

class Dad
 has_many :kids
 has_many :follows
end

class Mom
 has_many :kids
 geocoded_by :address
end

class Follow
 belongs_to :dad
end

class Kid
 belongs_to :mom
 belongs_to :dad
 belongs_to :user
end

With the Geocoder gem I'm trying to create a scope that takes in the total count of the Dad's Kids nearest to the User's location compared to the Kids Mom's locations that happened today.

<% @follows.each do |f| %>
 <% f.dad.kids.today.nearest.count
<% end %>

In my ApplicationController:

def set_user_location
  if signed_in?
   @user_location = current_user.address
  end
end

In my Kid model:

scope :today, -> { where("kids.created_at > ?", Time.now.beginning_of_day) }
scope :nearest, -> { joins(:mom).merge(Mom.near(@user_location, 2000)) }

But the nearest doesn't work. It doesn't load Moms at all.

User Load (0.6ms)  SELECT "users".* FROM "users" WHERE "users"."id" = 5 ORDER BY "users"."id" ASC LIMIT 1
Processing by FollowsController#index as HTML
  Follow Exists (0.3ms)  SELECT 1 AS one FROM "follows" WHERE "follows"."user_id" = $1 LIMIT 1  [["user_id", 5]]
  Follow Load (0.5ms)  SELECT "follows".* FROM "follows" INNER JOIN "dads" ON "dads"."id" = "follows"."dad_id" WHERE "follows"."user_id" = $1 ORDER BY name ASC LIMIT 30 OFFSET 0  [["user_id", 5]]
  Product Load (0.2ms)  SELECT "dads".* FROM "dads" WHERE "dads"."id" = $1 ORDER BY "dads"."id" ASC LIMIT 1  [["id", 39]]
   (0.7ms)  SELECT COUNT(*) FROM "kids" WHERE "kids"."dad_id" = $1 AND (kids.created_at > '2014-05-08 04:00:00.000000')  [["dad_id", 39]]
  CACHE (0.0ms)  SELECT COUNT(*) FROM "kids" WHERE "kids"."dad_id" = $1 AND (kids.created_at > '2014-05-08 04:00:00.000000')  [["dad_id", 39]]

What would be the correct way to write the nearest scope?

Upvotes: 1

Views: 120

Answers (1)

Mike Szyndel
Mike Szyndel

Reputation: 10593

Problem is with today scope, not nearest. Every model has sreated_at field so in your scope you should write

scope :today, -> { where("kids.created_at > ?", Time.now.beginning_of_day) }

EDIT: Another error is that you're referring to controller instance variable in model. Model and controller are separated so it will not work this way. Instead you should rewrite scope to

scope :nearest, ->(location, distance=2000) { joins(:mom).merge(Mom.near(location, distance)) }

and then in the controller you may write

Kid.nearest(some location goes here)

but I think your models are a little messed up and you want them to do something different. WhatI suppose you want to do is find a mother that is nearest to kid, so rather you should do something like

Mom.near(some_kid, 2000)

Upvotes: 1

Related Questions