Rails 3. Distinct query - ruby-on-rails-3

I am developing a Rails 3 application (which acts as an API) and I allow
people to send in a bunch of email address (via an iPhone app) and then automatically
search the database for matching members (through emails).
It is working now (below code) but is returning doubles if the user sends in more than one copy of each email.
#users = #emails.find_all {|profile| User.find_by_email(profile['email']) }
I want the api to only return one unique copy of the user if found.
I tried the below code but it does not work.
#users = #emails.find_all {|profile| User.select('DISTINCT email').where("LOWER (email) = ?", "%#{profile['email']}%") }
How can the first line of code above be changed to distinct lookups?
Thankful for all input!

I would take a look at
How do I get the unique elements from an array of hashes in Ruby?
a = [{:a => 1},{:a => 2}, {:a => 1}]
a.inject([]) { |result,h| result << h unless result.include?(h); result }
# this returns : [{:a=>1}, {:a=>2}]
Seems like to be what you need!

Related

Podio App Create not respecting Field external_id

I'm running into an issue with the Podio App Create API call:
https://developers.podio.com/doc/applications/add-new-app-22351
It does not appear to respect external_id for fields.
For example, given:
...
[fields] => Array
(
[0] => Array
(
[type] => text
[external_id] => title
[config] => Array
(
[label] => Name
...
The resulting field will have an external id of "name" and not "title".
This is a rather big issue as when trying to make exact copies of apps (into places that clone won't go), the change in field ids causes GF flows to break.
Any way around this?
Per the API documentation there is no "external_id" input in this call. The external IDs are always a standardized version of the field label though. (e.g. if you have 2 Name fields the first will be "name" and the second will be "name-2").
Alternatively, you could just run "get app" https://developers.podio.com/doc/applications/get-app-22349 to see what the external IDs ended up being.

Rails: Class method scoping on the properties of an associated model

This is a somewhat more complicated version of the question I asked previously.
Background:
So what I need is to display a list of articles. An article belongs to a media outlet. A media is located in a particular country and publishes articles in a particular language. So the data structure is as follows:
Article belongs to Media; Media has many Articles
Media belongs to a Country; Country has many Media
Media belongs to a Language; Language has many Media
Now, if I wanted to filter articles by media, I could use the following class method (I prefer class methods over scopes, because I am passing a parameter and am using a conditional statement inside the method):
def self.filter_by_media(parameter)
if parameter == "all"
all
else
where(media_id: parameter)
end
end
Question:
How to write a class method that would filter Articles based by properties of its associated model, the Media? For example, I want to get a list of articles published by media located a certain counrty or in several countries (there is also a default country when the user does not make any choice). Here’s what I tried:
# parameter can be either string 'default' or an array of id’s
def self.filter_by_country(parameter)
if parameter == "default"
joins(:media).where(media: [country_id: 1])
else
joins(:media).where(media: [country_id: parameter])
end
end
But that doesn’t work, and I am not conversant enough with SQL to figure out how to make this work. Could you please help?
Update:
I’m trying out #carlosramireziii's suggestion. I changed arrays into hashes (don't know what possessed me to use arrays in the first place), but I’m getting the following error in the Rails console (to avoid confusion, in my database, media is called agency):
def self.filter_by_country(parameter)
if parameter == "default"
joins(:agency).where(agency: {country_id: 1})
else
joins(:agency).where(agency: {country_id: parameter})
end
end
in Rails console:
> Article.filter_by_country('default')
=> Article Load (1.9ms) SELECT "articles".* FROM "articles" INNER JOIN "agencies" ON "agencies"."id" = "articles"."agency_id" WHERE "agency"."country_id" = 1
PG::UndefinedTable: ERROR: missing FROM-clause entry for table "agency"
LINE 1: ...ON "agencies"."id" = "articles"."agency_id" WHERE "agency"."...
^
: SELECT "articles".* FROM "articles" INNER JOIN "agencies" ON "agencies"."id" = "articles"."agency_id" WHERE "agency"."country_id" = 1
Update 2
My mistake in the Update section above is that I did not pluralize agency in the where clause. The part where(agency: {country_id: 1}) should have read where(agencies: {country_id: 1}). The pluralized word agencies here refers to the name of the table that is being joined.
You are very close, you just need to use a nested hash instead of an array.
Try this
def self.filter_by_country(parameter)
if parameter == "default"
joins(:media).where(media: { country_id: 1 })
else
joins(:media).where(media: { country_id: parameter })
end
end

MailChimp API Get Subscribers ammount

I have been looking at the mailchimp api, and am wondering how to display the live ammount of subscribers to a list, is this possible? And is it possible to have this counter LIVE? I.e as users join, the number increases in real time?
EDIT:
I have been getting used to the API slightly...
after using Drewm's mailchimp php wrapper its starting to make more sense...
I have so far
// This is to tell WordPress our file requires Drewm/MailChimp.php.
require_once( 'src/Drewm/MailChimp.php' );
// This is for namespacing since Drew used that.
use \Drewm;
// Your Mailchimp API Key
$api = 'APIKEY';
$id = 'LISTID';
// Initializing the $MailChimp object
$MailChimp = new \Drewm\MailChimp($api);
$member_info = $MailChimp->call('lists/members', array(
'apikey' => $api,
'id' => $id // your mailchimp list id here
)
);
But not sure how to display these values, it's currently just saying 'array' when I echo $member_info, this maybe completly because of my ignorance in PHP. Any advice to s
I know this may be old, but maybe this will help someone else looking for this. Latest versions of API and PHP Files.
use \DrewM\MailChimp\MailChimp;
$MailChimp = new MailChimp($api_key);
$data = $MailChimp->get('lists');
print_r($data);// view output
$total_members = $data['lists'][0]['stats']['member_count'];
$list_id = $data['lists'][0]['id'];
$data['lists'][0] = First list. If you have more, then it would be like $data['lists'][1] ect...
And to get a list of members from a list:
$data = $MailChimp->get("lists/$list_id/members");
print_r($data['members']);// view output
foreach($data['members'] as $member){
$email = $member['email_address'];
$added = date('Y/m/d',strtotime($member['timestamp_opt']));
// I use reverse dates for sorting in a *datatable* so it properly sorts by date
}
You can view the print_r output to get what you want to get.

How to test a search controller action which has filters in Rails with RSpec?

We have a bar with filters in almost all of our table-based views in a rails app and we need to test the controller action.
An example of the code:
def index
#users = User.
with_status(params[:status]).
with_role(params[:role_id]).
search(params[:q])
end
The above methods are ActiveRecord scopes which are setup to be bypassed if the passed value if blank.
What I need to do now is spec it sanely and test all the esge cases:
no params passed
only role, only status, only search
role + status, role + search, ... (pairs of 2)
role + status + search
The basic spec example I have written is as follows:
context "when filtering by status" do
before do
1.times { Factory(:user, :status => "one") }
3.times { Factory(:user, :status => "other") }
end
it "returns only users with the provided :status" do
get :index, :status => "one"
assigns(:users).size.should == 1
assigns(:users)[0].status.should == "one"
end
end
I want to write a matrix that will mix and match the role, status and search params and generate the appropriate spec examples.
Is the Array#permutation the solution or is there a better way to do it?
I would test the scopes in the model, so make sure that they can handle the blank value correctly, and also handle the set value correctly.
Then inside the controller, I would test the expectation that the chain is called (use stub_chain). The fact that the chain will return the correct result is handled by the fact that each scope individually has the correct behaviour (you tested that), and the combined behaviour is ensured by rails/activerecord. You should test the passed parameters are handled correctly.
The code you built to test the matrix is very impressive. But for me I try to make sure that my tests are readable, I consider them a kind of documentation of what a piece code is expected to do. To me your code is not comprehensible at first sight.
Hope this helps.

Mapped two arrays... now... can i map three?

This mapping worked:
#fbc = FbComments.where("reviewee_id = ?", current_user.id)
#users = User.order("last_name")
#fb_comments = #fbc.map! { |fb| [fb, #users.find_by_id(fb.user_id)] }
So two arrays are mapped... one with comments and one with the user data of the person that made the comments. But I also need the user's profile picture data. Do i change the original mapping method to include a third array somehow (e.g. #fbc + #users + #pictures), or do i have to map another array on the result of mapping the first two (e.g. #fb_comments + #pictures)?
Profile pictures, like comments, have a user_id that is matched to the id of the user who made the comments.
Thanks.
I'm not sure why you're doing this the way you are. Why not use a join (.includes) to get everything in one query?
#fbc = FbComments.where("reviewee_id = ?", current_user.id).includes(:user => :picture)
#fbc.first.user # => The first user in the results
#fbc.first.user.picture # => The first user's picture
(I'm assuming here that profile picture data is its own model called Picture. Change it to fit your app if necessary.)
Take a look at the documentation and scroll down to "Eager loading of associations."