Adding a tab to project/setting tab [Redmine] - ruby-on-rails-3

I use this code to add a tab to project/setting tab in ProjectHelper module:
def project_settings_tabs
tabs = [{...},
.....,
{name: => 'polls', :action => :poll, :partial => '../.. /path_to_partial', :label => :poll }
]
tabs.select {|tab| User.current.allow_to?(tab[:action], #project)}
end
However, my Polls tab didn't display on setting tab as I expected. So my question is what is problems with my code and is there any other way to add a tab to setting tab?

I have found the solution: in init.rb file, add this line: permission :polls, { :polls => [:index, :vote] }, :public => true to set permission for poll tab and then the tab will display correctly.

Related

Remove default dropdown option added by required true in Rails 5

I have a select dropdown option that is required but its option are dynamically added. So there's a scenario wherein the select dropdown is empty.
= s.input :test_id, :label => "Choose Category", :collection => #model.categories, :required => true
My question is how can I remove the blank option added automatically when you set your dropdown as required (I wanted my dropdown to be empty). I've tried adding include_blank: false but I'm getting an ArgumentError - include_blank cannot be false for a required field.:
Should work with:
= s.input :test_id, :label => "Choose Category", :collection => #model.categories, :required => true, prompt: ''

Updating from Rails 2 to Rails 3 with JQuery AJAX

I am moving a site from Rails 2 to Rails 3 and need to replace the following deprecated methods, with JQuery:
periodically_call_remote
button_to_remote
In the view, there is a button that when pressed executes a callback every 12 seconds:
#index.html.erb (Rails 2.2.2)
<%= periodically_call_remote(:url => { :action => 'check' }, :frequency => '12', :update => 'log') %>
[...]
<div id="generate_test_btn"><%= button_to_remote "Generate Test Order",
:url => { :action => "check", :should_generate => "YES" },
:update => "log" %>
</div>
[...]
#controller
def check
[...Generate content...]
render :partial => "log" and return
end
My Partial Implementation
Not sure how to glue button_to code to the JQuery AJAX stuff
### index.html.erb (Rails 3.1)
<script>
$(document).ready(function(){
$("#generate_test_button").click(function() {
setInterval(updateTest,12000);
});
});
function updateTest(){
$("#log").load("???");
}
</script>
<%= button_to "Generate Test Order",
{ :controller => :test, :action=> :check, :should_generate => "YES" },
{ :remote => true }
%>
in rails 3 you have unobtrusive javascript
so basically, any link you create with :remote => true would call that controller#action but with a js.erb ending
so in your case the button would call the check action in the test controller
if you create a check.js.erb and place it in the views/test folder and have inside
alert("UJS!");
it should pop up once you press that button
also note that you should have the rails-ujs gem and require it in the application.js manifest

Allowing User to Download File from S3 Storage

Right now I am using Amazon S3 and Paperclip which is allowing my users to upload an image that is associated with the event they are creating. My ultimate goal is since others can view this event, to be able to click on the image and have it prompt a SAVE TO their computer. As of now, clicking the link will open the image in a browser window. I rather have it ask for them to download instead. All images only saved on S3, not local. Need to hide exposed s3 url as well if possible or camouflage it
Here is my current setup
Index.html
<%= link_to 'Download Creative', event.creative.url, class: "btn btn-info" %>
Event.rb
has_attached_file :creative,
:styles => { :thumb => "150x150", :custcreative => "250x75" },
:path => ":attachment/:id/:style.:extension",
:s3_domain_url => "******.s3.amazonaws.com",
:storage => :s3,
:s3_credentials => Rails.root.join("config/s3.yml"),
:bucket => '*****',
:s3_permissions => :public_read,
:s3_protocol => "http",
:convert_options => { :all => "-auto-orient" },
:encode => 'utf8'
Hoping someone can help me out.
To avoid extra load to your app (saving dyno's time in Heroku), I would rather do something like this: add this method to your model with the attachment:
def download_url(style_name=:original)
creative.s3_bucket.objects[creative.s3_object(style_name).key].url_for(:read,
:secure => true,
     :expires => 24*3600,  # 24 hours
     :response_content_disposition => "attachment; filename='#{creative_file_name}'").to_s
end
And then use it in your views/controllers like this:
<%= link_to 'Download Creative', event.download_url, class: "btn btn-info" %>
To make this work, I've just added a new action in the controller, so in your case it could be:
#routes
resources :events do
member { get :download }
end
#index
<%= link_to 'Download Creative', download_event_path(event), class: "btn btn-info" %>
#events_controller
def download
data = open(event.creative_url)
send_data data.read, :type => data.content_type, :x_sendfile => true
end
EDIT:
the correct solution for download controller action can be found here (I've updated the code above): Force a link to download an MP3 rather than play it?
Now in aws-sdk v2, there is a method :presigned_url defined in Aws::S3::Object, you can use this method to construct the direct download url for a s3 object:
s3 = Aws::S3::Resource.new
# YOUR-OBJECT-KEY should be the relative path of the object like 'uploads/user/logo/123/pic.png'
obj = s3.bucket('YOUR-BUCKET-NAME').object('YOUR-OBJECT-KEY')
url = obj.presigned_url(:get, expires_in: 3600, response_content_disposition: "attachment; filename='FILENAME'")
then in your views, just use:
= link_to 'download', url
event = Event.find(params[:id])
data = open(event.creative.url)
send_data data.read, :type => data.content_type, :x_sendfile => true, :url_based_filename => true
end
You need to set the "Content-Disposition" to "attachment" in your HTTP response header. I'm not a Rails developer - so just Google it and you'll see plenty of examples - but it probably looks something like this:
:content_disposition => "attachment"
or
...
:disposition => "attachment"

Problem using :default => {:format => 'pdf'} in Rails 3

I want to route requests something like this: reports/bloodtypes is routed to controller reports, action bloodtypes, with format = pdf, and the route named as bloodtype_report. The Guides gives an example
match 'photos/:id' => 'photos#show', :defaults => { :format => 'jpg' }
When I do this:
match 'reports/bloodtypes' => 'reports#bloodtypes', :defaults => {:format => 'pdf'}, :as => 'bloodtype_report'
or this
match 'reports/bloodtypes' => 'reports#bloodtypes', :format => 'pdf', :as => 'bloodtype_report'
the controller still does not receive the :format => 'pdf' in params, and tries to render the report as HTML. The funny thing is that the route is shown by Rake as
bloodtype_report : /reports/bloodtypes(.:format) : {:format=>"pdf", :controller=>"reports", :action=>"bloodtypes"}
whether I use the first form (with :default) or second (just setting the format to pdf). It seems the route is correct, so why is the format parameter not being passed to the controller?
have you tried adding this to your controller:
respond_to do |format|
format.html
format.pdf { render :pdf => "show" }
end

What's the alternative of :before & :after of rails 2.3.* in Rails 3?

I am using remote form in Rails 3. It works fine but I want to show / hide spinner during ajax request.
In rails 2.3.* we use :before & :after in remote form to show/hide spinner
What should I do in Rails 3, as remote form of Rails 3 doesn't contain such options.
Here is a working solution I tried:
In my view file, I use :onSubmit to show a spinner:
<% form_for("", #search,
:url => {:action => "search"},
:html => {:id => "search_form",
:onSubmit => "$('search-loader').show();"},
:remote => true) do |f| %>
In my search action, I added one line to hide it:
render :update do |page|
...
page << "$('search-loader').hide();"
end
It works great..!
Well, I'm using jQuery, and I'm doing the following, trying to be unobtrusive:
Add this, right before your </head> tag:
= yield :document_ready
Then in your application_helper.rb:
def document_ready(content)
html = %{ $(function(){#{content}})}
content_for(:document_ready){ javascript_tag(html) }
end
This allows you to load and run javascript once your document is loaded.
On top of the view containing your form add:
- document_ready("hide_button_show_spinner('your_button_id')")
In application.js
function hide_button_show_spinner(element_id) {
$('#'+element_id).bind('click', function() {
$('#'+element_id).after("<img src='/path/to/your/spinner.gif' class='ajax_loader' id='"+element_id+"_ajax_loader' style='display: none'/>")
$('#'+element_id).hide();
$('#'+element_id+'_ajax_loader').show();
});
}
This will hide the button and show the spinner once the button is clicked. You may need to adapt this to your specific case.
You can then show the button and hide the spinner in your javascript response (the .js.erb file that you render from the action called by the ajax request).