I'm messing with Rack::Affiliates but I don't know if it works with the domain localhost in development environment.
1º This is my config in application.rb file:
config.middleware.use Rack::Affiliates, {:param => 'aff_id', :ttl => 6.months, :domain => '.localhost'}
2º I send a email with a link and param aff_id something like:
<%= link_to "accept invite", new_user_registration_url(:aff_id => #user.id) %>
3º In root action:
def index
if request.env['affiliate.tag'] && affiliate = User.find_by_affiliate_tag(request.env['affiliate.tag'])
logger.info "Halo, referral! You've been referred here by #{affiliate.name} from #{request.env['affiliate.from']} # #{Time.at(env['affiliate.time'])}"
else
logger.info "We're glad you found us on your own!"
end
respond_to do |format|
format.html
end
end
I'm getting the message on console:
We're glad you found us on your own!
What am I doing wrong?
Thanks!
Did you remember to include config.middleware.use Rack::Affiliates in your config/application.rb file?
If not, add it and see what happens.
Otherwise you can try debugging by changing the if statement to:
if request.env['affiliate.tag']
logger.info "request.env['affiliate.tag'] = #{request.env['affiliate.tag']}"
else
logger.info "We're glad you found us on your own!"
end
This should tell you if the affiliate.tag is getting set and if so to what value.
It's all due to User.find_by_affiliate_tag. have you any column named affiliate_tag.
If your are inviting using this link <%= link_to "accept invite", new_user_registration_url(:aff_id => #user.id) %> where you are using #user.id as aff_id.
So you have to use User.find_by_id instead of User.find_by_affiliate_tag
Final code snippet of exmaple contoller will look like
class ExampleController < ApplicationController
def index
str = if request.env['affiliate.tag'] && affiliate = User.find_by_id(request.env['affiliate.tag'])
"Halo, referral! You've been referred here by #{affiliate.name} from #{request.env['affiliate.from']} # #{Time.at(env['affiliate.time'])}"
else
"We're glad you found us on your own!"
end
render :text => str
end
end
Related
So I'm trying to create a feature for Typo (blogging app) that merges two articles in one. For some reason, I can't manage to save the merged article. I have followed several threads here, read over and over Rails and Ruby docs... And Can't figure out why it doesn't work
Besides finding what's wrong with my code, I'd like to know best solutions to see what's going on 'under the hood', to debug the code. Eg: See when methods are called, what parameters are passed...
Here is my code:
View:
<% if #article.id && #user_is_admin %>
<h4>Merge Articles</h4>
<%=form_tag :action => 'merge_with', :id => #article.id do %>
<%= label_tag 'merge_with', 'Article ID' %>
<%= text_field_tag 'merge_with' %>
<%= submit_tag 'Merge' %>
<% end %>
<% end %>
Controller
def merge_with
unless Profile.find(current_user.profile_id).label == "admin"
flash[:error] = _("You are not allowed to perform a merge action")
redirect_to :action => index
end
article = Article.find_by_id(params[:id])
debugger
if article.merge_with(params[:merge_with])
flash[:notice] = _("Articles successfully merged!")
redirect_to :action => :index
else
flash[:notice] = _("Articles couldn't be merged")
redirect_to :action => :edit, :id => params[:id]
end
end
Model:
def merge_with(other_article_id)
other_article = Article.find_by_id(other_article_id)
if not self.id or not other_article.id
return false
end
self.body = self.body + other_article.body
self.comments << other_article.comments
self.save!
other_article = Article.find_by_id(other_article_id)
other_article.destroy
end
Thanks in advance, and sorry if this is a rookie question :)
You did not mentioned what problem you are facing while saving, you just said you could not manage to save so I can't help you with that unless you provide some stack trace.
I will mention a few things though:
first is in your controller method you have multiple redirection code like redirect_to :action => index without any return from method so I think you will get multiple redirect or render error at some point like when unless executes and redirects but code continues the execution and throws error so try to reduce these redirects or mention it like redirect_to :action => index and return.
Then in model merge_with you are assigning other_article twice, you don't need the second one.
about debugging, you can create some puts line inside code and check it in rails server console to verify that the condition is executed like in controller method after if article.merge_with you can put:
puts "merge sucess"
and check console when merge action is called, if you see "merge sucess" then if block executed.
OR
use byebug like you used debugger. It will stop the execution where it will find the byebug word and will give access to a live session in rails console.
if you put it where you have debugger you can access the console and do the operations manually like run:
article.merge_with(params[:merge_with])
then see what happens. or put before self.save! in model and save it manually in console and check errors like self.errors.messages.
Stack trace is also helpful to see line by line code execution and identify the error.
I will update this if you post any info about what error you are facing
In my application.html.erb I have <%= render #objects %>, that renders a bunch of _object.html.erb partials, each with a <%= link_to(object) %>. I render the same single partial <%= render #object %> in the email that is being sent when somebody leaves a comment but I want link to start with a server url.
I have tried everything:
link_to(object)
url_for(object)
before_filter :set_mailer_host
def set_mailer_host
ActionMailer::Base.default_url_options[:host] = request.host_with_port
end
default_url_options[:host] = "example.com"
def default_url_options
{ host: 'example.com' }
end
...Nothing works. With or without :only_links
In the end, I just built a dumb helper that prepends hostname to links:
# application_controller.rb
before_filter { App::request=request }
# application_helper.rb
def hostify obj
"http://#{App::request.host_with_port}#{url_for obj}"
end
# _object.html.erb:
<%= link_to obj.title, hostify(object) %>
Is there a normal way to do this?
I can't really tell what you're trying to link to or what 'obj' is referring to, but you can do something like:
link_to obj.title, {:host => 'example.com'}
or
link_to obj.title, {:controller => 'store', :action => 'view_cart', :host => 'example.com'}
Okay after spending some time with it, I think I am starting to figure it out.
You got to use restful routes then you can set default_url_options[:host] = host in the Mailer action and :only_path to true in default_url_options for other controllers. Plus :locale.
And in the view I have: objects_url(object)
Since I have different hostnames, I pass request.host_with_port as a parameter from a controller to the Mailer when sending mail.
link_to doesn't accept parameters and url_for() can only build url from parts of it.
def url_options
{ domain: 'example.com' }
end
Or better to merge in case you use other options:
def url_options
{ domain: 'example.com' }.merge(super)
end
I'd like to add a custom filter field to "Add News" page in Redmine,
so that when I add a new news I could select group of users the email should be sent to.
The field itself is a list of Redmine User groups and every user is assigned to at least 1 of them.
Has anybody done this? Any suggestions would be appreciated
I've located the 3 files related to the issue:
/app/controller/news_controller.rb
/app/models/news.rb
/app/views/news/_form.html.erb
Environment:
Redmine version 2.2.1.stable.11156
Ruby version 1.8.7 (x86_64-linux)
Rails version 3.2.11
Environment production
Database adapter MySQL
Redmine plugins:
no plugin installed
So far I've done only 1 modification in Redmine, which sends added news to all registered users.
File: /app/modelsmailer.rb
Overview:
EDIT: Following your advice I moved mailer function to the controller:
def create
#news = News.new(:project => #project, :author => User.current)
#news.safe_attributes = params[:news]
#news.save_attachments(params[:attachments])
if #news.save
#news_added(#news)
if params[:group]
mail :to => GroupsUser.find(params[:group][:ids]).joins(:users).select("users.mail").compact,
:subject => "[#{#news.project.name}] #{l(:label_news)}: #{#news.title}"
else
render :new
end
end
end
But I'm getting error: NameError (uninitialized constant NewsController::GroupsUser): pointing to line
mail :to => GroupsUser.find
news_controller.rb:
def new
#news = News.new
#groups = GroupsUser.all
end
news/_form.html.erb:
<%= label_tag :group_ids "Groups"
<%= collection_select :group, :ids, #groups, :id, :name, {}, multiple: true %>
Edit:
I'm going to have to take a few guesses on what your controllers look like, but I'll give you something close. Based on the mailer function you provided, I'm assuming that was called out of the create controller after the News was saved. I would call the mail function after that. Something like this:
def create
news = News.new(params[:news]
if news.save
news_added(news)
send_mail_to_groups(params[:group][:ids]) if params[:group]
redirect_to ...
else
render :new
end
end
The mailing part should be removed from news_added
def news_added(news)
redmine_headers 'Project' => news.project.identifier
#author = news.author
message_id news
#news = news
#news_url = url_for(:controller => 'news', :action => 'show', :id => news)
end
in favor of its own new routine:
send_mail_to_users_by_group_ids(group_ids)
# Woo: Sent to all users, despite their email settings
mail :to => GroupsUser.find(group_ids).joins(:users).select("users.mail").compact,
:subject => "[#{#news.project.name}] #{l(:label_news)}: #{#news.title}"
end
You might want to add a where clause to only include active users.
I think that's about right. I'm doing it off the top of my head so there's probably a typo or error or two in there. Hopefully it points you in the right direction though.
I am having a bit of an issue with getting tumblr working within a rails app.
This is the snippet of code which results in a 400 error (meaning that there was an incorrect parameter)
#postcontent = #post.content.gsub(/<\/?[^>]*>/, "")
post = Tumblr::Post.create(:email => 'valid#email', :password => 'mypassword', :type => 'video', :embed
=> #post.video_html, :caption => #postcontent)
I have checked the API docs and checked my code and code content being rendered, and it still does not want to work.
The funny thing is that it worked previously. It was working about a week ago. Has something changed with tumblr?
Update: I have also posted this on github in the issues section, and discovered that it's only with one of my posts that this method is not working, AND I have sent it over to the good people at tumblr. Has anyone else had this issue?
I HAVE WORKED THIS OUT ...
for anyone finding difficulty in this here is a solution.
Firstly, there was an error with the gem itself. Some code needs to be modified.
Check out this version of the gem:
http://github.com/mindreframer/tumblr
Secondly, as Tumblr allows html, I am calling sanitize within the controller to make my content nicely formatted and clean.
class PostsController < ApplicationController
include ActionView::Helpers::TextHelper
include ActionView::Helpers::SanitizeHelper
def tumblrsubmit
tumblruser = Tumblr::User.new('valid#email', 'validpass', false)
Tumblr.blog = 'blogname'
#post = Post.find(params[:id])
begin
unless #post.movie_id.nil? #checks if there is a movie ID
#tags = #post.tags.join(', ')
post = Tumblr::Post.create(tumblruser,
:type => 'video',
:embed => #post.video_html , #fetches the stored embed code
:caption => "Read Full Article & More at: <a href='http://www.mywebsite.com/posts/#{#post.slug}'>#{#post.title}</a> <p> </p>#{ActionController::Base.helpers.sanitize(#post.content)}",
:slug => #post.slug,
:tags => #tags )
else
post = Tumblr::Post.create(:tumblruser, :type => 'regular', :title => #post.title, :body => ActionController::Base.helpers.sanitize(#post.content), :slug => #post.slug)
end
#post.update_attributes(:tumbler_id => "#{post}") #updates the database with the new tumblr post id
flash[:notice] = "Successfully sent <strong>#{#post.title}</strong> to tumblr. with post id = #{post}"
rescue
flash[:error] = "You are unable to post <strong>#{#post.title}</strong> to tumblr at this time"
end
redirect_to :back
end
end
I know this seems like alot, but it does the job.
Hope this helps anyone else out there.
Cheers,
Matenia
does anyone know how to prevent the failing mechanism of link_to_unless_current?
f.e.: I have my page navigation with
link_to_unless_current "new task", new_task_path
When I click on the link, i come to the new taks path form... And no link is created -> ok.
Then I put incorrect values in the form and submit.
The TasksController processes the "create" action, the validation for the ActiveRecord-model fails because of the incorrect data and the controller renders the "new" action (and includes the error messages for the model).
class TasksController < ApplicationController
def create
#task = Task.new(params[:task])
if #task.save
flash[:notice] = 'task was successfully created.'
redirect_to(tasks_url)
else
render :action => "new"
end
end
end
But here the link gets created!
-> Because of the difference between the urls:
link path = new_task_path
but
posted path = tasks_path with :method => :post
Does anybody know how to cleanly solve this problem?
Thanks
Having a quick look at the source for link_to_unless_current...
...it makes use of current_path? such that you should be able to do something like this:
In a helper...
def current_page_in?(*pages)
pages.select {|page| current_page?(page)}.compact.any?
end
... and then in your view, you can just supply an array of either named_routes or hashes like Shadwell's answer above.
<%= link_to_unless(current_page_in?(new_thing_path, things_path), "add a thing") %>
You get the idea...
UPDATED
Had a think about this... and it'd be great if you could just use it like you'd hoped that the original method worked. Here we compare the supplied named route (or controller + action hash) with the current page AND its referrer.
def current_page_or_referrer_in(options)
url_string = CGI.unescapeHTML(url_for(options))
request = #controller.request
# We ignore any extra parameters in the request_uri if the
# submitted url doesn't have any either. This lets the function
# work with things like ?order=asc
if url_string.index("?")
request_uri = request.request_uri
referrer_uri = request.referrer
else
request_uri = request.request_uri.split('?').first
referrer_uri = request.referrer.split('?').first
end
#referrer_uri always has full path (protocol, host, port) so we need to be sure to compare apples w apples
if url_string =~ /^\w+:\/\//
["#{request.protocol}#{request.host_with_port}#{request_uri}", referrer_uri].include?(url_string)
else
referrer_uri = referrer_uri.gsub(request.protocol, '').gsub(request.host_with_port, '')
[request_uri, referrer_uri].include?(url_string)
end
end
The beauty is that it now lets you just do this (from your example):
<%= link_to_unless(current_page_or_referrer_in(new_task_path), "Add a task") %>
It'll then display if you're on new_task_path OR a page to which it has been sent (such as the create page
You can do it with link_to_unless instead of link_to_unless_current:
link_to_unless(controller_name == 'tasks' &&
(action_name == 'new' || action_name == 'create'),
new_task_path)