Facebooker: Getting it to post to specific pages? - facebooker

I am trying to post to specific pages and running into an issue. This is what I have where 1234 is a facebook uid
#user = Facebooker::User.new(1234)
#user.session = Facebooker::Session.create(KEY,SECRET)
my_page = Facebooker::Page.new(PAGE_NUMBER)
user.publish_to(#user, :message => #message)
It keeps posting to the user profile and not the page I specify. What am I doing wrong?

try (just a guess)
user.publish_to(my_page, :message => #message)

Related

Using user input to query MySQL database and move to next page or display error

When accessing the first page of our site, users are prompted to enter a "coupon code" to continue to the next page. Coupons can be used multiple times, but must exist in the "code" field of the coupon_codes table.
If the user enters a code that exists in the coupon_codes table, they should automatically be redirected to the next page. If the user enters a code that does not exist in the coupon_codes table, an error should be displayed with the option of trying again.
I'm sure I'm making this more difficult than it needs to be, as I've been working on this on and off for days. I've been able to get it to be what I feel is close, but not quite there. There have been multiple variations and trials, but this is where I'm currently at.
Model (coupon_code):
def self.code(code)
if code
self.exists?(['code = ?', "#{code}"])
##move on to /design
else
##display error
end
end
View (index):
<%= form_tag coupon_code, :method => 'get' do %>
<%= text_field_tag :code, params[:code] %>
<%= submit_tag("Check my coupon", :name => nil) %>
<% end %>
Controller:
def index
#coupon_codes = CouponCode.code(params[:code])
end
The log shows the following (after entering the correct code) before re-rendering the page I'm already on:
CouponCode Exists (0.2ms) SELECT 1 AS one FROM `coupon_codes` WHERE (code = 'correct') LIMIT 1
If I use the rails console, it seems like it should work (assuming I'm using it correctly), I'm just not sure how to go about getting it to move on or display an error.
2.1.1 :001 > code = 'correct'
=> "correct"
2.1.1 :002 > CouponCode.exists?(['code = ?', "#{code}"])
CouponCode Exists (0.2ms) SELECT 1 AS one FROM `coupon_codes` WHERE (code = 'T001') LIMIT 1
D, [2017-08-17T11:08:32.730761 #6788] DEBUG -- : CouponCode Exists (0.2ms) SELECT 1 AS one FROM `coupon_codes` WHERE (code = 'correct') LIMIT 1
=> true
2.1.1 :003 > code = 'wrong'
=> "wrong"
2.1.1 :004 > CouponCode.exists?(['code = ?', "#{code}"])
CouponCode Exists (0.2ms) SELECT 1 AS one FROM `coupon_codes` WHERE (code = 'wjorea') LIMIT 1
D, [2017-08-17T11:09:10.611964 #6788] DEBUG -- : CouponCode Exists (0.2ms) SELECT 1 AS one FROM `coupon_codes` WHERE (code = 'wrong') LIMIT 1
=> false
Again, I'm sure it's something simple and I'm just over thinking it. Sorry if I gave way too much detail... I figured too much is better than not enough. Thank you in advance for any help or direction!
My current code is based off of parts of this Stack Overflow question, if that helps any.
The problem here is the model is not and should not be concerned with controller or view issues. Redirecting to another page is explicitly a controller issue and must be handled directly in the controller.
What you want to do is reduce your model's code to an advisory position, it will advise the controller on how to handle the request. It will not take direct action.
For example:
class CouponCode
def self.code_exists?(code)
self.exists?(code: code)
end
end
Then in the controller:
if (Coupon.code_exists?(params[:code]))
redirect_to(coupon_exists_path(...))
end
Given how simple your check is, though, it's not clear if having such a method in the model is of any use since the alternative is simply:
if (Coupon.exists?(code: params[:code]))
redirect_to(coupon_exists_path(...))
end
That's one character more code on the controller and three lines less on the model.
I'm just not sure how to go about getting it to move on or display an
error.
You need to put that code in the controller. Its the controller's job to handle such things. Also you don't need a model method here. To keep the things straight forward and simple, try the below
def index
if CouponCode.exists?(code: params[:code])
#code for redirect to next page
else
flash.now[:notice] = "Your error message"
end
end

Ruby ActiveRecord Query with has_many Association

I have a system that has a User, Message, and MessageToken models. A User can create Messages. But when any User reads the Messages of others a MessageToken is created that associates the reader (User) to the Message. MessageTokens are receipts that keep track of the states for the user and that particular message. All of my associations in the Models are set up properly, and everything works fine, except for structuring a very specific query that I cannot get to work properly.
User.rb
has_many :messages
Message.rb
belongs_to :user
has_many :message_tokens
MessageToken.rb
belongs_to :user
belongs_to :message
I am trying to structure a query to return Messages that: Do not belong to the user; AND { The user has a token with the read value set to false OR The user does not have a token at all }
The later part of the statement is what is causing problems. I am able to successfully get results for Messages that are not the user, Messages that the user has a token for with read => false. But I cannot get the expected result when I try to make a query for Messages that have no MessageToken for the user. This query does not error out, it just does not return the expected result. How would you structure such a query?
Below are the results of my successful queries and the expected results.
130 --> # Messages
Message.count
78 --> # Messages that are not mine
Message.where.not(:user_id => #user.id)
19 --> # Messages that are not mine and that I do not have a token for
59 --> # Messages that are not mine, and I have a token for
Message.where.not(:user_id => #user.id).includes(:message_tokens).where(message_tokens: {:user_id => #user.id}).count
Message.where.not(:user_id => #user.id).includes(:message_tokens).where(["message_tokens.user_id = ?", #user.id]).count
33 --> # Messages that are not mine, and I have a token for, and the token is not read
Message.where.not(:user_id => #user.id).includes(:message_tokens).where(message_tokens: {:user_id => #user.id, :read => false}).count
Message.where.not(:user_id => #user.id).includes(:message_tokens).where(["message_tokens.user_id = ? AND message_tokens.read = false", #user.id]).references(:message_tokens).count
The Final Expected Result
52 --> # Messages that are not mine and: I have a token for that is not read OR I do not have a token for
My best attempt at a query to achieve my goal
64 --> # Wrong number returned, expected 52
Message.where.not(:user_id => #user.id).includes(:message_tokens).where(["(message_tokens.user_id = ? AND message_tokens.read = false) OR message_tokens.user_id <> ?", #user.id, #user.id]).references(:message_tokens).count
The problem lies in the query trying to find Messages that are not the users and that the user does not have a token for
63 --> #This does not yield the expected result, it should == 19 (the number of Messages that are not mine and that I do not have a token for)
Message.where.not(:user_id => #user.id).includes(:message_tokens).where.not(message_tokens: {:user_id => #user.id}).count
Message.where.not(:user_id => #user.id).includes(:message_tokens).where(["message_tokens.user_id <> ?", #user.id]).references(:message_tokens).count
How can I solve this?
If you don't mind using 2 queries, a possible solution would be:
messages_not_written_by_user = Message.where.not(:user_id => #user.id)
messages_already_read_by_user = Message.where.not(:user_id => #user.id).includes(:message_tokens).where(message_tokens: {:user_id => #user.id, :read => true})
messages_not_read_by_user_yet = messages_not_written_by_user - messages_already_read_by_user
I would personally find this syntax more readable:
messages_not_written_by_user = Message.where.not(:user => #user).count
messages_already_read_by_user = Message.where.not(:user => #user).includes(:message_tokens).where(message_tokens: {:user => #user, :read => true}).count
One remark to this query:
63 --> #This does not yield the expected result, it should == 19 (the number of Messages that are not mine and that I do not have a token for)
Message.where.not(:user_id => #user.id).includes(:message_tokens).where.not(message_tokens: {:user_id => #user.id}).count
This query searches for all the messages which have a token with an arbitrary other user. (If msg1 has a token with #user, and it also has a token with #another_user, this query will find it.)
Full disclosure - I'm not sure how I'd do this as you have it set up right now. However: are you against installing a gem to help? If you're not, I'd suggest you look into the Squeel gem (https://github.com/activerecord-hackery/squeel).
Squeel makes these kinds of associations a lot easier and allows use to use the plain old | operator. It's built on Arel and shouldn't effect anything you've written in ActiveRecord (at least in my experience). Hope that helps!
Ok, so thanks to the help of R11 Runner I was able to come up with a solution, which required using pure SQL. I could not use the Squeel gem or ActiveRecord as there was no equivalent to SQL's NOT EXISTS operator, which was the crucial component missing.
The reason this works is because unlike the other solutions the NOT EXISTS operator will return all records from the Messages table where there are no records in the MessageTokens table for the given user_id, whereas using where.not would look for the first match instead not ensuring the non existence that was needed.
Message.find_by_sql ["SELECT * FROM messages where messages.user_id <> ?
AND (
(EXISTS (SELECT * FROM message_tokens WHERE message_id = messages.id AND user_id = ? AND read = FALSE))
OR
(NOT EXISTS (SELECT * FROM message_tokens WHERE message_id = messages.id AND user_id = ?))
)",#user.id, #user.id, #user.id]

How do I correctly display fetched email content in Rails?

Here is the code I am using to fetch emails and store them into my DB:
emails = imap.search([fp.filter_type, "#{fp.value}"])
emails.each do |message_id|
msg = imap.fetch(message_id,'RFC822')[0].attr['RFC822']
mail = Mail.read_from_string msg
Email.create({
:user_id => self.id,
:message_id => message_id.to_s,
:email_from => mail.from[0],
:subject => mail.subject,
:content => mail.multipart? ? mail.html_part : mail.body.decoded,
:sent_at => mail.date
}) if !Email.find_by_message_id(message_id.to_s)
end
When I render the content for an email record, it is not displayed correctly. However the email looks great on my GMail account. I need a way to store the correct HTML and display it just like it would seem in my email account. I also need to parse data out of these emails which is difficult as the DOM structure gets really messed up.
Here is the working code:
emails = imap.search([fp.filter_type, "#{fp.value}"])
emails.each do |message_id|
msg = imap.fetch(message_id,'RFC822')[0].attr['RFC822']
mail = Mail.read_from_string msg
Email.create({
:user_id => self.id,
:message_id => message_id.to_s,
:email_from => mail.from[0],
:subject => mail.subject,
:content => mail.multipart? ? mail.html_part.body.to_s : mail.body.to_s,
:merchant_id => merchant.id,
:filter_id => filter.id,
:filter_property_id => fp.id,
:sent_at => mail.date
}) if !Email.find_by_message_id(message_id.to_s)
end
Email.all.collect {|e| e.run_parsers} if emails.size > 0 # ideally this should be initiated from email model
With this code I am able to get correct HTML and the view is exactly like in my GMail, well more or less.

Create an elsif statement in Rails API?

I am trying to receive a JSON post to my Rails 3 application. The JSON post is just an email with a subject which will be one of the following:
BACKUP_PASS/VERIFY_PASS
BACKUP_FAIL/VERIFY_FAIL
BACKUP_FAIL/VERIFY_PASS
etc..
I have the following code in my controller:
def backupnotification
email_payload = JSON.parse(params[:payload])
Activity.create(:action => 'failed to backup', :details => email_payload['recipient'], :user_id => '28')
end
I've also added the following to my routes file:
post '/api/activity/backupnotification' => 'activities#backupnotification'
Obviously, this would create a new Activity record regardless of the backup status. What I would like to do is create an activity with an action of failed to backup if the term FAIL appears anywhere in the subject, and successfully backed up if the term FAIL does not exist.
The JSON post (email_payload) includes an attribute called subject. I was wondering if I could do something like this:
if email_payload['subject'] => "FAIL"
...
else
...
end
What would be the best way of doing this?
Assuming you can access your subject in a similar way as your recipient, you can try something like this.
def backupnotification
email_payload = JSON.parse(params[:payload])
if email_payload['subject'].include?('FAIL')
action_message = 'failed to backup'
else
action_message = 'successfully backed up'
end
Activity.create(
:action => action_message,
:details => email_payload['recipient'],
:user_id => '28')
end

Issue with RoR ActionMailer --cannot send plaintext and HTML emails simultaneously.

I'm having an issue with my Rails application--I'm having trouble sending both a HTML and plaintext version of my email. NOTE: the email does send; however, it's not styled correctly... there is a link to the results below.
It's recommended everywhere that if you want to send HTML you should also send a plain text alternative too. Unfortunately, it appears that I'm doing something wrong, as my application does not allow me to send both HTML and plaintext, without the HTML looking very weird.
here is my mailer model:
class ProjectMembersMailer < ActionMailer::Base
def membership_invitation(membership)
#project = membership.project
#user = membership.user
mail( :subject => %(Invitation to join project #{#project.business_name}),
:from => %("App" <no-reply#appname.com>),
:to => #user.account.email,
:content_type => "text/html" ) do |format|
format.html
format.text
end
end
end
My project_member_mailer views have two files: membership_invitation.html.haml and membership_invitation.text.erb (please note that the second file is using .erb, but even if I convert it to a .haml extension for consistency I get the same error)
Here is picture of that the output looks like when I attempt to send it using the code above. Please note that I removed some of the text.
Basically it looks like it's sending the text version above the html version of the file. Is there an alternate way to sending both plaintext and HTML emails without this happening? Or am I missing something--like, should these emails not be sent simultaneously? Any help would be greatly appreciated. Thank you so much for your time and help!
According to the Action Mailer Rails Guide you do not need to use the "format" method, and should remove the "content-type" parameter too.
mail will automatically detect that there are both html and text templates and will automatically create the email as multipart/alternative
Just try:
mail( :subject => %(Invitation to join project #{#project.business_name}),
:from => %("App" <no-reply#appname.com>),
:to => #user.account.email)
I had the exact same problem, and it can be fixed with just one simple thing. Place format.text over format.html
def membership_invitation(membership)
#project = membership.project
#user = membership.user
mail( :subject => %(Invitation to join project #{#project.business_name}),
:from => %("App" <no-reply#appname.com>),
:to => #user.account.email,
:content_type => "text/html" ) do |format|
format.text
format.html
end
end