Rails: How to pass parameters from a model using an after_commit method, eventually to share on twitter
I'm trying to use an after_commit method to pass parameters from the post to the user model where it is shared to twitter with another method.
It works fine when I just pass it something from the post model like 'title' or 'content':
post.rb
after_commit :share_all
def share_all
if user.authentications.where(:provider => 'twitter').any?
user.twitter_share(title, content)
end
end
user.rb
def twitter_share(title, content)
twitter.update("#{title}, #{content}")
end
But this is as far as my understanding goes, I've read elsewhere that I could pass 'self' instead of 'title' and 'content', and still be able to use 'title' and 'content' plus any thing else from the model such as 'created_at'. However, I can't seem to get this working, I've tried this :
post.rb
def share_all
if user.authentications.where(:provider => 'twitter').any?
user.twitter_share(self)
end
end
user.rb
def twitter_share(self)
twitter.update("#{title}, #{content}")
end
And I get SyntaxError (/Users/ihal/Desktop/dayor/app/models/user.rb:118: syntax error, unexpected keyword_self, expecting ')' def twitter_share(self)
And it posts this to twitter #< Post:0x00000101d6e1e0>
My question is how to you properly setup passing 'self' so that any parameter could be called with twitter.update()?
Also how do you go about pulling out URL for the post, so that you could pass the URL to share on twitter?
Edit:
trying Rails.application.routes.url_helpers.post_url(@post, :host => 'myhost.com')
in post.rb
class Post < ActiveRecord::Base # line 19
after_commit :share_all
Rails.application.routes.url_helpers.post_url(@post, :host => 'myhost.com') #line 37
def share_all
if user.authentications.where(:provider => 'twitter').any?
user.twitter_share(self)
end
end
When I go to delete a post, I get the error :
Started POST "/posts/32" for 127.0.0.1 at 2011-04-15 14:57:17 -0700 Processing by PostsController#destroy as HTML Parameters: {"authenticity_token"=>"x8KkqLLCLdTOouUfCMzyWWmwxLIKThnE1n3rQNSkew8=", "id"=>"32"} User Load (1.1ms) SELECT "users".* FROM "users" WHERE ("users"."id" = 5) LIMIT 1 Completed in 82ms
ActionController::RoutingError (No route matches {:action=>"destroy", :controller=>"posts"}):
app/models/post.rb:37:in <class:Post>'
app/models/post.rb:19:in
'
app/controllers/posts_controller.rb:36:in `authorized_user'
Rendered /Users/ihal/.rvm/gems/ruby-1.9.2-p136@rails3gemset/gems/actionpack-3.0.1/lib/action_dispatch/middleware/开发者_StackOverflowtemplates/rescues/routing_error.erb within rescues/layout (1.2ms)
post controller
def destroy
@post.destroy
redirect_to root_path
end
private
def authorized_user
@post = Post.find(params[:id]) #line 36
redirect_to root_path unless current_user?(@spost.user)
end
end
Have you thought about using an Observer? That way you can keep the after_commit stuff, which does not appear to to belong in the model, in its proper place. Plus it helps simplify your model instead of cluttering it up.
For the syntax error, self
is a reserved word. Rename the variable name in the method declaration. So try something like:
def twitter_share(post)
# do stuff
end
To access the url helpers outside of the controller, use:
Rails.application.routes.url_helpers.post_url(@post, :host => 'myhost.com')
Don't forget to use the :host option when accessing the url helpers outside the controller so the helper has context.
what I can see in code is, title and content are attributes of Post. so passing them as theire name will be converted into their value.
now you are passing self in twitter_share from post then the post object will be passed to that method. you need to modified the twitter_share method as below to make it work
def twitter_share(post)
twitter.update("#{post.title}, #{post.content}")
end
def twitter_share(post)
twitter.update("#{post.title}, #{post.content}")
end
You are passing a Post into the user.twitter_share method.
精彩评论