Request-URI Too Long in REDMINE TIMESHEET PLUGIN - redmine

I am getting in redmine Request-URI Too Long
The requested URL's length exceeds the capacity limit for this server. whenever I try to select csv in timesheet plugin to export the timesheet report.
How do i solve this please tell me

The problem is the method. You are trying to retrieve too many parameters in the url and Apache (or any other like this one) have a limit of 2000 characters by default. In my case I didnt have access to the Apache server so changing the .conf file was not an option.
Looking into the forks of the repository I found someone who has already solved this issue. Here is a link to SashaH's pull request.
This pull request is fairly new so it's not committed yet.
Just change the code as indicated and the plugin should work as you want:
app/helpers/timesheet_helper.rb
:timesheet => timesheet.to_param)
end
- def link_to_csv_export(timesheet)
- link_to('CSV',
- {
- :controller => 'timesheet',
- :action => 'report',
- :format => 'csv',
- :timesheet => timesheet.to_param
- },
- :method => 'post',
- :class => 'icon icon-timesheet')
+ def form_for_csv_export(timesheet)
+ params_like_decode_url = CGI.unescape({:timesheet => timesheet.to_param}.to_query)
+ inputs = ""
+ form = form_tag :controller => 'timesheet', :action => 'report', :format => 'csv' do
+ params_like_decode_url.split("&").each do |param|
+ param_arr = param.split("=")
+ inputs << hidden_field_tag(param_arr.first, param_arr.last, :id => "")
+ end
+ inputs << submit_tag("CSV")
+ inputs.html_safe
+ end
+ form.html_safe
end
def toggle_arrows(element, js_function)
app/models/timesheet.rb
def to_csv
out = "";
+
+ handle_time_entries = {}
+ time_entries.each do |k,v|
+ if k.is_a? String
+ handle_time_entries[k] = v
+ next;
+ end
+ handle_time_entries[k.name] = v
+ end
+
+ time_entries = handle_time_entries
FCSV.generate(out, :encoding => 'u', :force_quotes => true) do |csv|
csv << csv_header
## -314,7 +325,7 ## def time_entries_for_user(user, options={})
return TimeEntry.includes(self.includes).
where(self.conditions([user], extra_conditions)).
- order('spent_on ASC')
+ order('spent_on ASC').references(self.includes)
end
def fetch_time_entries_by_project
app/views/timesheet/report.html.erb
<div class="contextual">
- <%= link_to_csv_export(#timesheet) %>
+ <%= form_for_csv_export(#timesheet) %>
<%= permalink_to_timesheet(#timesheet) %>
</div>
init.rb
require 'redmine'
## Taken from lib/redmine.rb
-#if RUBY_VERSION < '1.9'
-# require 'faster_csv'
-#else
-# require 'csv'
-# FCSV = CSV
-#end
+if RUBY_VERSION < '1.9'
+ require 'faster_csv'
+else
+ require 'csv'
+ FCSV = CSV
+end
if Rails::VERSION::MAJOR < 3
require 'dispatcher'

Related

How to update a field by itself in linq2db

I mean,
how can I translate the query
update myTable
set myField1 = myField1 + 1
where myField2 = 'xyz'
Thank you
There are several ways:
db.MyTable
.Where(x => x.MyField2 == "xyz")
.Set(x => x.MyField1, prev => prev.MyField1 + 1)
.Update();
db.MyTable
.Where(x => x.MyField2 == "xyz")
.Update(prev => new MyTable { MyField1 = prev.MyField1 + 1 });
db.MyTable
.Update(x => x.MyField2 == "xyz",
new MyTable { MyField1 = prev.MyField1 + 1 });

ActionController StrongParameters syntax embeded parameter

UPDATE regarding accessing uploaded_picture:
======>
The culprit was in ImageItem.rb where I had call to upload_picture as private. Apparently controller call with parms.require.permit is a public call to attr_accessor with before_create on that variable.
With regard to .create! and .update! this param def is working:
def item_image_params
params.require(:items).require(:item).require(:item_images).permit(:item_image_caption, :uploaded_picture)
end
===== >
Request parameters are exactly -- with regard to structure:
See below...
Parameters: {"utf8"=>"✓", "authenticity_token"=>"foo", "commit"=>"new_item",
"items"=>{"item"=>{"field_changed"=>"0", "item_type"=>"lend", "remote_ip"=>"", "item_id"=>"", "participant_id"=>"", "category_id"=>"1", "other_item_category"=>"", "item_description"=>"", "item_condition_id"=>"-2", "item_model"=>"", "item_count"=>"", "notify"=>"0", "comment"=>"", "item_images"=>{"participant_id"=>"", "item_image_id"=>"", "item_image_caption"=>""}},
"contact_preference"=>{"preference_field_changed"=>"1",
"contact_preference_id"=>"20", "item_id"=>"", "user_id"=>"19", "participant_id"=>"899", "use_which_contact_address"=>"0", "contact_by_chat"=>"0", "contact_by_email"=>"0", "contact_by_home_phone"=>"0", "contact_by_Facebook"=>"foo", "contact_by_LinkedIn"=>"foo", "contact_by_Twitter"=>"foo", "contact_by_Instagram"=>"foo", "contact_by_other_social_media"=>"1", "contact_by_other_social_media_access"=>"2"},
"lender_transfer"=>{"transfer_field_changed"=>"0", "lender_transfer_id"=>"foo", "item_id"=>"", "remote_ip"=>"", "participant_id"=>"foo", "user_id"=>"19", "borrower_comes_to_which_address"=>"3", "meetBorrowerAtAgreed"=>"0", "meetBorrowerAtAgreedBorrowerChoice"=>"0", "meetBorrowerAtAgreedMutual"=>"0", "thirdPartyPresenceMutual"=>"1", "borrower_returns_to_which_address"=>"3", "willPickUpPreferredLocation"=>"0", "comment"=>"fgfg"},
"lender_item_condition"=>{"condition_field_changed"=>"0", "lender_item_condition_id"=>"1", "item_id"=>"", "remote_ip"=>"", "participant_id"=>"foo", "user_id"=>"19", "small_fee_amount"=>"12.0", "available_for_purchase_amount"=>"", "trade_item"=>"12", "security_deposit_amount"=>"", "specific_conditions"=>"1221"}}, "id"=>"foo"}
This is not working:
def contact_preference_params
params.require(:contact_preference).permit(:item_id, :user_id, :use_which_contact_address,
:contact_by_chat, :contact_by_email, :contact_by_home_phone, :contact_by_cell_phone,
:contact_by_alternative_phone, :contact_by_Facebook, :contact_by_Twitter, :contact_by_Instagram,
:contact_by_LinkedIn, :contact_by_other_social_media, :contact_by_other_social_media_access)
end
Nor this:
def contact_preference_params
params.require(:items).require(:contact_preference).permit(:item_id, :user_id, :use_which_contact_address,
:contact_by_chat, :contact_by_email, :contact_by_home_phone, :contact_by_cell_phone,
:contact_by_alternative_phone, :contact_by_Facebook, :contact_by_Twitter, :contact_by_Instagram,
:contact_by_LinkedIn, :contact_by_other_social_media, :contact_by_other_social_media_access)
end
def contact_preference_params called from:
def update_cp
#pid = params[:items][:item][:participant_id]
#item_id = params[:items][:contact_preference][:item_id]
#current_item = nil
if #item_id.nil?
#current_item = ContactPreference.create!(contact_preference_params)
else
#cp = ContactPreference.where("participant_id = :pid and item_id = :iid", {pid: #pid, iid: #item_id }).first
#current_item = #cp.update!(contact_preference_params)
end
#current_item
end
Discovered I had an error in def, def update_cp
What worked is:
def contact_preference_params
params.require(:items).require(:contact_preference).permit(:item_id, :user_id, :use_which_contact_address,
:contact_by_chat, :contact_by_email, :contact_by_home_phone, :contact_by_cell_phone,
:contact_by_alternative_phone, :contact_by_Facebook, :contact_by_Twitter, :contact_by_Instagram,
:contact_by_LinkedIn, :contact_by_other_social_media, :contact_by_other_social_media_access)
end
====== >> UPDATE
Discovered another problem;
ERROR: ActiveModel::UnknownAttributeError (unknown attribute 'uploaded_picture' for ItemImage.):
Request param:
Parameters: {"utf8"=>"✓", "authenticity_token"=>"", "commit"=>"new_item",
"items"=>
{"item"=>{"field_changed"=>"1", "item_type"=>"lend", "remote_ip"=>"", "item_id"=>"", "participant_id"=>"", "category_id"=>"1", "other_item_category"=>"", "item_description"=>"ghfg", "item_condition_id"=>"3", "item_model"=>"fghgf", "item_count"=>"12", "notify"=>"0", "comment"=>"fgh gfhfg fghgf",
"item_images"=>{"item_image_id"=>"", "item_id"=>"", "uploaded_picture"=>#, #original_filename="foo.jpg", #content_type="image/jpeg", #headers="Content-Disposition: form-data; name=\"items[item][item_images][uploaded_picture]\"; filename=\"1[1].jpg\"\r\nContent-Type: image/jpeg\r\n">, "item_image_caption"=>"foo"}}}, "id"=>""}
How does one access items => item => item_image => uploaded picture when uploaded_picture is an attr_acessor in model.rb
item_image.rb
class ItemImage < ApplicationRecord
belongs_to :item
attr_accessor :uploaded_picture, :item_type
before_save :uploaded_picture
private
def uploaded_picture=(picture_field)
unless (picture_field.blank?)
begin
name = self.item_id.to_s + '_' +
File.basename(picture_field.original_filename).gsub(/[^\w._-]/, '')
directory = './app/assets/images/' + self.item_type.to_s
path = File.join(directory, name)
# write the file -- b is for binary
File.open(path, "wb") { |f| f.write(picture_field.read) }
self.image_file_name = name
self.image_content_type = picture_field.content_type.chomp
self.image_width = 0
self.image_height = 0
.... end
image_image table:
Field | Type | Null | Key | Default | Extra
item_image_id | int(11) | NO | PRI | NULL | auto_increment |
|
item_id | varchar(40) |
image_content_type | varchar(20) |
image_height | int(3) |
image_width | int(3) |
image_file_name | varchar(150) |
item_image_caption | varchar(50) |
...
html.erb
...
<%= item_images.hidden_field :item_image_id %>
<%= item_images.hidden_field :item_id %>
<%= f.hidden_field :item_type, :value => #itype %>
<div style="margin-left:25px;margin-top:5px;float:left;">
<%= item_images.label :uploaded_picture, "Image of Item" %>
<%= item_images.file_field :uploaded_picture %>
<% if #ii %>
<% if #ii.image_file_name %>
<% #imageLibrary = #imageLibrary + "/" + #ii.image_file_name %>
<% end %>
<% end %>
...
ItemsController
def update_item
...
unless #current_item.nil?
#itemImageRecord = #current_item.item_images.update!(item_image_params)
else
#itemImageRecord = #current_item.item_images.create!(item_image_params)
def item_image_params
params.require(:items).require(:item).permit(:item_images).permit(:item_id, :item_type, :item_image_caption, :uploaded_picture)
end
ERROR: ActiveModel::UnknownAttributeError (unknown attribute 'uploaded_picture' for ItemImage.):

How to check existance and nil in single line for variable in ruby on rails

def import_update
require 'csv'
file = params[:file]
CSV.foreach(file.path, headers: true) do |row|
#prod = Spree::Product.find(row["id"])
#var = Spree::Variant.find_by(product_id: #prod.id)
Spree::Product.where(:id => row["id"]).update_all(:name => row["name"] if !row[name].nil?.present?, :meta_description => row["meta_description"], :shipping_category_id => row["shipping_category_id"], :description => row["description"], :meta_keywords => row["meta_keywords"], :tax_category_id => row["tax_category_id"], :available_on => row["available_on"], :deleted_at => row["deleted_at"], :promotionable => row["promotionable"], :meta_title => row["meta_title"], :featured => row["featured"], :supplier_id => row["supplier_id"])
end
end
I want check that row is present or not. if it is present then it updated when it is not null and condition is in single line because I want to apply this for all variable in updation statement.I wrote code above but showing error.
Try this:
params = ["name","meta_description","shipping_category_id","description","meta_keywords","tax_category_id","available_on","deleted_at","promotionable","meta_title","featured","supplier_id"
hash = {}
params.each do |param|
if row[param]
hash[param] = row[param]
end
end
Spree::Product.where(:id => row["id"]).update_attributes(hash)
This will let you keep your code dry.
EDIT:
What are these lines supposed to do?:
#prod = Spree::Product.find(row["id"])
#var = Spree::Variant.find_by(product_id: #prod.id)
I presume you don't have several entries with one ID. And your not using the objects that you retrieved in those two lines, so simply write the method like this:
def import_update
require 'csv'
file = params[:file]
params = ["name","meta_description","shipping_category_id","description","meta_keywords","tax_category_id","available_on","deleted_at","promotionable","meta_title","featured","supplier_id"]
CSV.foreach(file.path, headers: true) do |row|
hash = {}
params.each do |param|
if row[param]
hash[param] = row[param]
end
end
Spree::Product.find(row["id"]).update_all(hash)
end
end

count columns is not automatically updated, have to run counter_culture_fix_counts to fix each time add new record

I'm using counter_culture to create survey applications
the problem is each time I add citizen the count columns is not automatically update
I have to go to console and run Citizen.counter_culture_fix_counts
below is my model and controller for reference
I'm using rails 4 and nested_attributes
thank you for help
model
class Familycard < ActiveRecord::Base
has_many :citizens , :dependent => :destroy
accepts_nested_attributes_for :citizens, :allow_destroy => :true
end
class Citizen < ActiveRecord::Base
belongs_to :familycard
counter_culture :familycard,
:column_name => Proc.new { |model| "#{model.sex}_count"},
:column_names => {
["citizens.sex = ? ", 'male'] => 'males_count',
["citizens.sex = ? ", 'female'] => 'females_count'
}
counter_culture :familycard
counter_culture :familycard,
:column_name => Proc.new { |model| "#{model.job}_count"},
:column_names => {
["citizens.job = ? ", 'Entrepreneur'] => 'Entrepreneurs_count',
["citizens.job = ? ", 'House wife'] => 'housewifes_count',
["citizens.job = ? ", 'Student'] => 'students_count',
["citizens.job = ? ", 'Veteran'] => 'veterans_count',
}
end
controller
class FamilycardController < ApplicationController
def new
#familycard = Familycard.new(:citizens => [Citizen.new])
end
def create
#familycard = Familycard.new(familycard_params)
if #familycard.save
flash[:success] = "Data Saved"
redirect_to familycards_path
else
render 'familycards/familycard_form'
end
end
follow up some comments from my question, I have solved my problem above, and below are sample code for condition for the gem
counter_culture :parent_model, :column_name => Proc.new {|child_model|
if child_model.published_condition == 'CONDITION 1'
"condition1_count"
elsif child_model.published_condition == 'CONDITION 2'
"condition2_count"
elsif child_model.published_condition == 'CONDITION 3'
"condition3_count"
end
}, :column_names => {
["child_models.published_condition = ?", 'CONDITION 1'] => 'condition1_count',
["child_models.published_condition = ?", 'CONDITION 2'] => 'condition2_count',
["child_models.published_condition = ?", 'CONDITION 3'] => 'condition3_count'
}
explanation:
parent_model has 3 fields to save the total number which are condition1_count,condition2_count and condition3_count

Drupal services endpoint returns 404 : Could not find resource retrieve

I followed this tutorial :
http://pingv.com/blog/an-introduction-drupal-7-restful-services
and seems everyone have the same problem as mine in the comments.
I made a rest service with drupal services module :
Server = REST
path = api/mohtadoon
mohtadoon_api.module file
<?php
/**
* Implements of hook_services_resources().
*/
function mohtadoon_api_services_resources() {
$api = array(
'mohtadoon' => array(
'operations' => array(
'retrieve' => array(
'help' => 'Retrieves mohtadoon data',
'callback' => 'mohtadoon_api_stories_retrieve',
'file' => array('file' => 'inc', 'module' => 'mohtadoon_api','name' => 'resources/mohtadoon_api'),
'access arguments' => array('access content'),
),
),
),
);
return $api;
}
mohtadoon_api.inc file in resources/mohtadoon_api path
<?php
function mohtadoon_api_stories_retrieve() {
return mohtadoon_api_find_stories();
}
function mohtadoon_api_find_stories() {
// Compose query
$query = db_select('node', 'n');
$query->join('node_revision', 'v', '(n.nid = v.nid) AND (n.vid = v.vid)');
$query->join('users', 'u', 'n.uid = u.uid');
$query->join('field_data_body', 'b', '((b.entity_type = \'node\') AND (b.entity_id = n.nid) AND (b.revision_id = n.vid))');
$query->fields('v', array('timestamp', 'title'));
$query->addField('u', 'name', 'author');
$query->addField('b', 'body_value', 'content');
$query->condition('n.type', 'stories', '=');
$items = $query->execute()->fetchAll();
return $items;
}
?>
when I access the path
http://localhost/mohtadoon01/?q=api/mohtadoon/retrieve
where mohtadoon01 is project path AND ?q= because
the request result is 404 Not found: Could not find resource retrieve.
why is this happens && how to debug something like this ... I didn't deal with drupal before and want to make only one get web service.
You likely need to url encode your string:
http://localhost/mohtadoon01/?q=api%2Fmohtadoon%2Fretrieve
Can't promise this will work though, depending on your drupal configuration.
Slashes are allowed in query string, as per RFC: http://ietf.org/rfc/rfc3986.txt, however many services out of the box do not: you may need to enable AllowEncodedSlashes.
I encountered exactly the same thing using Services 7.x-3.7. To understand the issue, I looked through the following file:
services/servers/rest_server/includes/RESTServer.inc
Given the definition of your service, the code exercised by GET requests for your resource should be:
protected function resolveController($resource, &$operation) {
...
if ( $request_method == 'GET'
&& $canon_path_count >= 1
&& isset($resource['operations']['retrieve'])
&& $this->checkNumberOfArguments($canon_path_count, $resource['operations']['retrieve'])
&& !empty($canonical_path_array[0])
) {
$operation_type = 'operations';
$operation = 'retrieve';
}
...
}
If we now take a look at the code for $this->checkNumberOfArguments():
// We can see from the snippet above that $args_number = $canon_path_count and hence that
// $args_number is always greater than 0
protected function checkNumberOfArguments($args_number, $resource_operation, $required_args = 0) {
$not_required_args = 0;
if (isset($resource_operation['args'])) {
foreach ($resource_operation['args'] as $argument) {
if (isset($argument['source']) && is_array($argument['source']) && isset($argument['source']['path'])) {
if (!empty($argument['optional'])) {
$not_required_args++;
}
else {
$required_args++;
}
}
}
}
// This is where we fall down; Since the service definition does not include any args,
// both $required_args and $not_required_args will equal zero when we get here. Not a problem
// for the first condition (1 >= 0), but clearly the second condition (1 <= 0 + 0) will evaluate
// to false and hence the argument count will not be accepted. As a result, the services module
// does not accept this controller and reports this as '404 not found'
return $args_number >= $required_args && $args_number <= $required_args + $not_required_args;
}
Try adding an argument to your service definition like this:
<?php
/**
* Implements of hook_services_resources().
*/
function mohtadoon_api_services_resources() {
$api = array(
'mohtadoon' => array(
'operations' => array(
'retrieve' => array(
'help' => 'Retrieves mohtadoon data',
'callback' => 'mohtadoon_api_stories_retrieve',
'file' => array('file' => 'inc', 'module' => 'mohtadoon_api','name' => 'resources/mohtadoon_api'),
'access arguments' => array('access content'),
'arg' => array(
array(
'name' => 'entity',
'type' => 'string',
'description' => 'Entity to operate on',
'source' => array('path' => '0'),
'optional' => TRUE,
'default' => '0',
),
),
),
),
),
);
return $api;
}
EDIT:
I think what is confusing people reading the blog post that you linked to (and I was one of those!) is that the URL given as the accessor for the service includes as its final parameter the name of the method that it was intended to invoke ('retrieve'). You could replace 'retrieve' with pretty much anything and the service should still respond (e.g. '/api/blog/pink-rabbit' or, in your case, 'api/mohtadoon/pink-rabbit'). The web service definitions themselves do not indicate what value of parameters can be passed to the endpoint. What counts is what HTTP method is used to access the service and how many parameters are passed to the endpoint (zero or more). Some types of operation require at least a certain number of parameters (e.g. 'retrieve' operations require at least one parameter to identify the specific thing that you want to retrieve).