create object to call retweeted_by_user [duplicate] - ruby

This question already has an answer here:
How to create instance of Twitter::Tweet to create retweeted_by_user
(1 answer)
Closed 8 years ago.
I am using the Ruby Twitter gem. I want to call retweeted_by_user(user, options = {}). How do I create instance of object to call this method. It is instance method, correct?
I did this for Twitter::REST::CLIENT
client = client = Twitter::REST::Client.new do |config|
config.consumer_key = "..."
config.consumer_secret = "..."
config.access_token = "..."
config.access_token_secret = "..."
end
but it does not work for Twitter::Tweet
client = client = Twitter::Tweet.new do |config|
config.consumer_key = "..."
config.consumer_secret = "..."
config.access_token = "..."
config.access_token_secret = "..."
end

1) What does the code you posted have to do with calling retweeted_by_user()?
2) I want to call retweeted_by_user(user, options = {}). How do I create instance of object to call this method. It is instance method, correct?
If you go to the twitter gem website:
https://github.com/sferik/twitter
...then click on the Documentation link, it takes you here:
http://rdoc.info/gems/twitter
...then if you click on Method List in the upper right corner, and look down the list for retweeted_by_user(), and click on that link, it takes you to the method definition here:
http://rdoc.info/gems/twitter/Twitter/REST/Timelines#retweeted_by_user-instance_method
...then if you scroll to the top of that page, you can see that the method is defined in a module called:
Twitter::REST::Timelines
In ruby, modules are included in a class, and then instances of that class can call the (instance)methods defined in the module. What classes include the Twitter::REST::Timelines module? At the top of the page it says:
Included in:API
If you click on the API link, it takes you here:
http://rdoc.info/gems/twitter/Twitter/REST/API
and at the top of that page it says Module: Twitter::REST::API.
Okay, a module can also include another module, which means it's as if the including module itself defines the methods in the included module. But we still need to find a class somewhere that includes that module, and at the top of the page under Module: Twitter::REST::API, it says Included in:Client, and if you click on the Client link, it takes you here:
http://rdoc.info/gems/twitter/Twitter/REST/Client
and that page says Class: Twitter::REST::Client...and that means that objects of the class Twitter:REST::Client can call the method retweeted_by_user(), so you can write something like this:
results = Twitter::REST::Client.new.retweeted_by_user(....)
In fact, on the page documenting Twitter::REST::Client, there is a heading called Instance Methods, and if you scroll down the list of methods the docs show all the instance methods that come from included modules, e.g.
Methods included from Timelines: #home_timeline, #mentions_timeline,
#retweeted_by_me, #retweeted_by_user, #retweeted_to_me,
#retweets_of_me, #user_timeline
In regards to your code here:
client = client = Twitter::REST::Client.new do |config|
config.consumer_key = "..."
config.consumer_secret = "..."
config.access_token = "..."
config.access_token_secret = "..."
end
the docs say this about Twitter::REST::Client.new(),
Constructor Details
This class inherits a constructor from Twitter::Client
If you click on the Twitter::Client link, it says:
- (Twitter::Client) initialize(options = {}) {|_self| ... }
What that means is: if you call Twitter::REST:Client.new() and you specify a block with one parameter, ruby will pass the new Twitter::Rest::Client instance to the block, and then you can call retweeted_by_user() on that object, e.g.:
Twitter::REST::Client.new do |twitter_rest_client_instance|
results = twitter_rest_client_instance.retweeted_by_user(....)
...
end

Related

Class methods vs Instances when using Page object model in ruby

I hope you are having a great day!
I'm wandering something, when using the POM (Page object model) we always create new instances of our classes, like the following simple example:
class LoginPage
def initialize(driver)
#driver = driver
end
def click_button
#driver.find_element(xpath: "//button[#title='Login']").click
end
end
# We create a new instance and we click the button
login_page = LoginPage.new(driver)
login_page.click_button
This makes sense for me, we can create multiple pages if we need to, we can update the state of whatever we need.
However, if we only would have one page open at the time, and we know nothing changes, doesn't it make more sense to take a class method based approach like?:
class LoginPage
class << self
def click_button
#driver.find_element(xpath: "//button[#title='Login']").click
end
end
end
# We create a new instance and we click the button
LoginPage.click_button
Please let me know your ideas, and if you have tried this approach before

getting a Twitter::Cursor object with the Twitter gem

I'm playing around with the Ruby Twitter gem and wish to use the methods that are available on the Cursor object. For example, using the Twitter::Cursor I'm supposed to be able to get a an array of all friends by doing
client.friends.to_a
or get a most recent follower with
client.friends.first
However, in my attempt below, when tried to do client.friends.first for kanyewest, I got an error which showed that I'm using the Twitter::User object, not the Twitter::Cursor
undefined methodfriends' for #
How can I use the gem to get a cursor object that will allow me to query Kanye's friends.
client.friends.to_a
Note, I read the documentation for creating a new cursor object but I found it a little abstract. I'm not sure if you're supposed to call the constructor directly? If so, please show me how I'd do that
- (Twitter::Cursor) initialize(attrs, key, klass, request)
My Failing code
#!/usr/bin/env ruby
require 'rubygems'
require 'twitter'
client = Twitter::REST::Client.new do |config|
config.consumer_key = "8nwa....."
config.consumer_secret = "Wj20r....."
config.access_token = "363......"
config.access_token_secret = "7eydU2n....."
end
kanyewest = client.user("kanyewest")
puts kanyewest.friends.first
client.friends("kanyewest").first should work. friends is a method on client not on Twitter::User

Variable URL with Instance Variables

I know I'm being an idiot here, but I can't think of how this is done. I am creating an app with certain interests and am using a a Wikipedia scrape set up using Nokogiri. I have two inputs: Title and Wikipedia, but want to fill Summary and Content in the data model using the scrape. I want to use the Wikipedia attribute as a variable in a url within a method, but keep getting the error dynamic constant assignment PAGE_URL = "http://en.wikipedia.org/w/i....
I thought that the methods should go in the model, with reference to them in the Create definition under the controller, but this doesn't seem to work.
EDIT
I've just tried taking the constants out of the methods as suggested, but I am still getting a dynamic constant assignment error. My model currently looks like this:
PAGE_URL1 = "http://en.wikipedia.org/w/index.php?title="
PAGE_URL2 = "&printable=yes"
def get_PAGE_URL
PAGE_URL = PAGE_URL1 + self.wikipedia + PAGE_URL2
end
def get_page
page = Nokogiri::HTML(open(PAGE_URL))
end
def get_summary
get_PAGE_URL
self.summary = page.css("p")[0].text
end
def get_full_page
get_PAGE_URL
puts page.css('div#content.mw-body div#bodyContent div#mw-content-text.mw-content-ltr p').each do |p|
self.content = puts p.text
end
end
Constants can't go inside of methods, they must be defined inside of the class' direct scope.
Edit:
For example:
class WikiScraper
PAGE_URL = "http://www.wikipedia.org/"
def scrape
page_num = '5'
my_url = PAGE_URL + page_num
end
end

`send_tweet': undefined method `update' for nil:NilClass (NoMethodError)

I've been looking for the answer to my problem forever. For some reason I get this error: send_tweet': undefined methodupdate' for nil:NilClass (NoMethodError)'
whenever I try to run my ruby script. I don't know how to fix this.
Here's the code:
class TwitterConnect
def intialize
#client = Twitter::REST::Client.new do |config|
config.consumer_key = "CONSUMER KEY"
config.consumer_secret ="CONSUMER SECRET"
config.access_token = "ACCESS TOKEN"
config.access_token_secret = "ACCESS TOKEN SECRET"
end
#client.middleware.insert_after Twitter::Response::RaiseError, CustomMiddleware
end
def send_tweet (twitterMessage = "Hello world!")
#client.update("New TwitterConnect object intialized")
puts twitterMessage
end
end
If this is all the code you have, your send_tweet method isn't working because #client is never defined. You'll need to fix a couple things to make it work.
First, to have any access, you'll need to create a new instance of the class.
tc = TwitterConnect.new
Then, you'll be able to access your client instance variable within your newly created TwitterConnect object.
tc.send_tweet
If, alternatively, you are already doing this step and still getting the error, the problem is likely in the authentication of your config variables within the initialize method.
Hope that helps!

Ruby 1.9.2: How to change scope/binding of a block

Hi I have something like the folowing:
class TrialRequest
attr_accessor :trial_email
def initialize(email)
#trial_email = email
puts "Trial_email: #{trial_email}"
end
def create
#email = ::Gmail.connect!(gmail_name, gmail_password) do |gmail|
email = gmail.compose do
to 'trial#domain.com'
from trial_email
subject trial_email
text_part do
content_type 'text/html; charset=UTF-8'
body 'Sign me up.'
end
end
#binding.pry
gmail.deliver!(email)
end
end
end
The problem is that inside the compose block trial_email is not defined:
NameError: undefined local variable or method `trial_email' for #<Mail::Message:0x0000000431b830>
Is this a Ruby 1.9 issue or a gmail gem issue?
How should I go about making this method 'visible'/within the scope of the compose block?
Update:
This is an issue/feature of the gmail gem - ruby 1.9 blocks have changed but not this much!
In addition to the accepted answer, another workaround is to pass the data in as a method parameter:
def create(trial_email)
...
end
Looks like a GMail issue to me. Inside the blocks, self will be some object from the GMail gem so that you can have to, from, and similar DSL niceties available. You should be able to put self.trial_email into a local variable and then access that inside the blocks:
email_address = self.trial_email
#email = ::Gmail.connect!(gmail_name, gmail_password) do |gmail|
email = gmail.compose do
to 'trial#domain.com'
from email_address
subject email_address
#...
You're expecting (as you're entitled to) that the block should preserve the value of self, as it usually does. It looks like the gmail gem is using instance_exec here which allows it to change the value of self for the block to an instance of Mail::Message (which is why you can call to and from in that block even though you define no such methods)
While instance_exec is handy for producing nice DSLs, it is not without its downsides. Local variable scope isn't affected so you could store either trial_email or self in a local variable prior to the block and then use that local variable inside the block
The problem is that the block you pass to compose method is later passed to Mail.new and finally to Message.new (if I traced the chain correctly) and then this block is evaluated like that here:
instance_eval(&block)
As it's performed inside initialize method of a different object (instance of Message class) you do not have access to attributes of your TrialRequest object.
You can do the same thing without having any troubles like that:
email = gmail.compose
email.to = 'trial#domain.com'
email.from = trial_email
email.subject = trial_email
email.text_part do
content_type 'text/html; charset=UTF-8'
body 'Sign me up.'
end

Resources