I am trying to parse URLs. For example where I am trying to pull out:
~/locations/1 => [locations,1]
~/locations/1/comments => [locations,1]
~/locations/1/comments/22 => [locations,1]
~/locations/1/buildings/3 => [buildings,3]
~/locations/1/buildings/3/comments => [buildings,3]
~/locations/1/buildings/3/comments/34 => [buildings,3]
The format is pretty consistent. I started with arrays but it seems to still fail:
#request_path = request.path.downcase.split('/')
#comment_index = #request_path.index("comments").to_i
if #comment_index > 0
#request_path = #request_path.drop_while { |i| i.to_i >= #comment_index }
end
resource, id = #request_path.last(2)
I added the downcase just incase someone manually typed in an uppercase URL. The drop_while seems to not be working.
What kind of output you have after processing your code?
Edited
Your problem is that you convert element to_i and it is 0. But you want to compare index of element, but can normally get index of element in that situation using Array#index method.
Correct approach:
#request_path.drop_while { |i| #request_path.index(i) >= #comment_index }
You can parse path without drop_while.
My solution:
def resource_details(path)
resource_array = path.downcase.split("/").reject!(&:empty?)
key = resource_array.index("comments")
return key.present? ? (resource_array - resource_array[key..key + 1]).last(2) : resource_array.last(2)
end
It will cut out ["comments"] or ["comments","2"] for your path.
Invoke that method:
1.9.3p0 :051 > resource_details("/locations/1/buildings/3/comments")
=> ["buildings", "3"]
1.9.3p0 :052 > resource_details("/locations/1/comments/2")
=> ["locations", "1"]
Related
This is the controller code:
$player1QID = time().'.'.$request->player1_Id->extension();
$images1= $request->player1_Id->move(public_path('images'), $player1QID);
$player2QID = time().'.'.$request->player2_Id->extension();
$images2= $request->player2_Id->move(public_path('images'), $player2QID);
///this is adding to database:
$registeredusers = Registrations::create([
'tournament_id' => $request->input('tournament_id'),
'player1_name' => $request->input('player1_name'),
'player1_email' => $request->input('player1_email'),
'player1_Id' => $player1QID,
'player1_gender' => $request->player1_gender,
'player1_phone' => $request->input('player1_phone'),
'player2_name' => $request->input('player2_name'),
'player2_email' => $request->input('player2_email'),
'player2_Id' => $player2QID,
'player2_gender' => $request->player2_gender,
'player2_phone' => $request->input('player2_phone'),
'category' => $request->category,
'status' => $request->input('status'),
]);
This is in view blade:
Upload image1
Upload image2
Really appreciate if someone can help
you should first look at your inspection in Chrome, Firefox or whatever you are using, and check what your request contains, I mean if you are sending the images in separate names like:
...
player1_Id:
player2_Id:
...
i think, of course is sending like that because you are receiving it on your controller. Then try save it with datetime at end of name like:
public function obtainImage(Request $request){
$image1=request('player1_Id');
$this->manageImage($image1);
$image2=request('player2_Id');
$this->manageImage($image2);
}
public function manageImage($image){
$fileImageNameExtencion=$image->getClientOriginalName();
$fileName=pathInfo($fileImageNameExtencion, PATHINFO_FILENAME);
$fileExtencion=$image->getClientOriginalExtension();
$newFileName=$fileName."_".time().".".$fileExtencion;
$saveAs=$image->storeAs('public/images',$newFileName);
return $newFileName;
}
where $ newFileName is what you need to save to your database
otherwise you can do a dd ($ player1QID. '-'. $ player2QID) before saving to database and comparing names
I want to select Cars from database with where clause looking for best DRY approach for my issue.
for example I have this two parameters
params[:car_model_id] (int)
params[:transmission_id] (int)
params[:from_date]
params[:to_date]
but I dont know which one will be null
if params[:car_model_id].nil? && !params[:transmission_id].nil?
if params[:from_date].nil? && params[:from_date].nil?
return Car.where(:transmission_id => params[:transmission_id])
else
return Car.where(:transmission_id => params[:transmission_id], :date => params[:from_date]..params[:to_date])
end
elseif !params[:car_model_id].nil? && params[:transmission_id].nil?
if params[:from_date].nil? && params[:from_date].nil?
return Car.where(:car_model_id=> params[:car_model_id])
else
return Car.where(:car_model_id=> params[:car_model_id], :date => params[:from_date]..params[:to_date])
end
else
return Car.where(:car_model_id=> params[:car_model_id], :transmission_id => params[:transmission_id], :date => params[:from_date]..params[:to_date])
end
what is best approach to avoid such bad code and check if parameter is nil inline(in where)
You can do:
car_params = params.slice(:car_model_id, :transmission_id).reject{|k, v| v.nil? }
and then:
Car.where(car_params)
Explanation: Since, you're checking if the particular key i.e.: :car_model_id and transmission_id exists in params. The above code would be something like this when you have just :transimission_id in params:
Car.where(:transmission_id => '1')
or this when you have :car_model_id in params:
Car.where(:car_model_id => '3')
or this when you'll have both:
Car.where(:transmission_id => '1', :car_model_id => '3')
NOTE: This will work only when you have params keys as the column names for which you're trying to run queries for. If you intend to have a different key in params which doesn't match with the column name then I'd suggest you change it's key to the column name in controller itself before slice.
UPDATE: Since, OP has edited his question and introduced more if.. else conditions now. One way to go about solving that and to always keep one thing in mind is to have your user_params correct values for which you want to run your queries on the model class, here it's Car. So, in this case:
car_params = params.slice(:car_model_id, :transmission_id).reject{|k, v| v.nil? }
if params[:from_date].present? && params[:from_date].present?
car_params.merge!(date: params[:from_date]..params[:to_date])
end
and then:
Car.where(car_params)
what is best approach to avoid such bad code and check if parameter is
nil inline(in where)
Good Question !
I will make implementation with two extra boolean variables (transmission_id_is_valid and
car_model_id_is_valid)
transmission_id_is_valid = params[:car_model_id].nil? && !params[:transmission_id].nil?
car_model_id_is_valid = !params[:car_model_id].nil? && params[:transmission_id].nil?
if transmission_id_is_valid
return Car.where(:transmission_id => params[:transmission_id])
elseif car_model_id_is_valid
return Car.where(:car_model_id=> params[:car_model_id])
....
end
I think now is more human readable.
First, I would change this code to Car model, and I think there is no need to check if params doesn't exists.
# using Rails 4 methods
class Car < ActiveRecord::Base
def self.find_by_transmission_id_or_model_id(trasmission_id, model_id)
if transmission_id
find_by trasmission_id: trasmission_id
elsif model_id
find_by model_id: model_id
end
end
end
In controller:
def action
car = Car.find_by_transmission_id_or_model_id params[:trasmission_id], params[:car_model_id]
end
edit:
This code is fine while you have only two parameters. For many conditional parameters, look at ransack gem.
I'm trying to render an Infragistics Grid as part of my view in my MVC application. However, I'm trying to do the following:
#(Html.Infragistics()
.Grid(Model)
.ID("grid")
.Width("100%")
.Height("500px")
.PrimaryKey("ID")
.AutoGenerateColumns(false)
.AutoGenerateLayouts(false)
.Columns(column =>
{
column.For(x => x.omkt).HeaderText("OMKT").Width("30%");
column.For(x => x.dmkt).HeaderText("DMKT").Width("30%");
column.For(x => x.ibu).HeaderText("IBU").Width("20%");
column.For(x => x.count_total).HeaderText("COUNT_ALL").Width("20%");
})
.Features(features =>
{
features.Sorting().Type(OpType.Remote);
features.Paging().Type(OpType.Remote);
features.Filtering().Type(OpType.Remote);
})
.DataSourceUrl(Url.Action("GetMarketAreaData?ibu=" + ViewBag.IBU + "&sort=" + ViewBag.sort + "&startDate=" + ViewBag.startDate + "&endDate=" + ViewBag.endDate))
.Render()
)
The problem is on the DataSourceUrl line, where it's transforming all the ? and & characters into their escape sequences. Using \ doesn't work either, as I get a parser error for an unrecognized escape sequence. The reason why I need this, though, is because all of those are passed in as parameters into the controller function in order to pull the correct data.
As a result, I'm getting a 400 error when pulling the data. Is there any way to force the action to recognize ? characters for ? characters?
Found the answer: I needed to pass in a second parameter into Url.Action with all the parameters.
.DataSourceUrl(Url.Action("GetMarketAreaData", new { ibu = ViewBag.IBU, sort = ViewBag.sort, startDate = ViewBag.startDate, endDate = ViewBag.endDate }))
Any ideas what it takes to get this to work? I can't for the life of me figure it out.
def get_prices(c)
#print_prices = {}
Billing.where(:name => c).column_names.each do |d|
if d.match(/^print_/)
#print_prices[d] = d.value
end
end
return #print_prices
end
I've got no idea what to substitute d.value for.
Cheers for any help.
The following code will perform the query, returned in the form of a relation, and reject all items in the attribute key-value hash which do not match the given regex, which, in this case, is /^print_/.
def get_prices(c)
Billing.where(:name => c).first.attributes.reject{ |i| !i.match(/^print_/) }
end
Alternatively, it can also be written as:
def get_prices(c)
Billing.where(:name => c).first.attributes.select{ |i| i.match(/^print_/) }
end
When a user submits a link, is there a way to validate if he have included the http:// or not. I other words, is it possible to not only validate but also add the http:// if it is missing?
I am using Rails 3.
You could override the setter method for the link. In your model, something like this:
def link=(str)
str = 'http://' + str if str[0,7] != 'http://'
super(str)
end
This would force adding http:// to the start of all links if not already there.
You can use a custom validation.
Pretending your model is "Post" and the attribute is "url" you can use something like:
class Post < ActiveRecord::Base
validate :ensure_valid_url
protected
def ensure_valid_url
protocol_regexp = %r{
\A
(https?://)
.*
\Z
}iux
self.url = "http://" + url unless url.blank? or url.match(protocol_regexp)
ipv4_part = /\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5]/ # 0-255
regexp = %r{
\A
https?://
([^\s:#]+:[^\s:#]*#)?
( (xn--)?[[:alnum:]\w_]+([-.][[:alnum:]\w_]+)*\.[a-z]{2,6}\.? |
#{ipv4_part}(\.#{ipv4_part}){3} )
(:\d{1,5})?
([/?]\S*)?
\Z
}iux
default_message = 'does not appear to be a valid URL'
default_message_url = 'does not appear to be valid'
options = { :allow_nil => false,
:allow_blank => false,
:with => regexp }
message = url.to_s.match(/(_|\b)URL(_|\b)/i) ? default_message_url : default_message
validates_format_of(:url, { :message => message }.merge(options))
end
end
This example is based on validates_url_format_of
variation on Steve Lorek's answer taking in the account that some links submitted by user will contain https:// instead of http://
def link=(str)
str = 'http://' + str if (str[0,7] != 'http://' && str[0,8] != 'https://')
super(str)
end