I have a Rails 3.2 app, where Angular code is calling a Rails route. I need to pass the route the (Rails) id of the page, and am having some difficulty. I have embedded the id onto the page using a hidden div, but cannot access it from Angular, in order to pass back into Rails.
I've reviewed this blogpost: http://spin.atomicobject.com/2013/11/22/pass-rails-data-angularjs/
Here is a similar question:
Rails route params in angular
I seem to be getting something but it is an object, not the id I need. A button is pressed which triggers the Angular call. An example url on the page would be, in which case I am trying to pass 833:
http://0.0.0.0:3000/batches/833/edit
worksheet.js.coffee
#WorksheetCtrl = ($scope) ->
.
.
$scope.exportCSV = ->
batchId = angular.element(document.querySelector("#data-batch-id"))
location.href = "/wizards/#{batchId}/worksheet_export.csv?#{Object.toQueryString($scope.getPostParams())}"
config/routes.rb
match 'wizards/:id/worksheet_export', :to => 'wizards#worksheet_export', :as => 'worksheet_export'
app/views/batches/edit.html.erb
<div ng-controller="WorksheetCtrl" ng-init="init()">
<div id="div-passed-data" data-batch-id="<%= #batch.id %>"></div>
app/controllers/wizards_controller.rb
def worksheet_export
Rails.logger.debug "id: #{params[:id]}"
Rails.logger.debug "params: #{params}"
.
.
Rails Console
Started GET "/wizards/[object%20Object]/worksheet_export.csv" for 127.0.0.1 at 2014-01-12 21:52:31 +0100
Processing by WizardsController#worksheet_export as CSV
Parameters: {"id"=>"[object Object]"}
id: [object Object]
params: {"controller"=>"wizards", "action"=>"worksheet_export", "id"=>"[object Object]", "format"=>"csv"}
SOLVED -- better solutions welcome
It seems rather convoluted, but I managed to pass in the id via the init() method and from there added it to the $scope.
app/views/batches/edit.html.erb
<div ng-controller="WorksheetCtrl" ng-init="init(<%= #batch.id %>)">
worksheet.js.coffee
$scope.init = (batch_id)->
console.log("batch: #{batch_id}")
$(document).ready ->
$('#editCriteriasModal').on 'hidden', ->
$scope.$apply ->
$scope.criteriaListValidation $scope.modalCriteriaList
$scope.search()
$scope.batchId = batch_id
.
.
$scope.exportCSV = ->
location.href = "/wizards/#{$scope.batchId}/worksheet_export.csv?#{Object.toQueryString($scope.getPostParams())}"
Related
I am using rails 3 and fragment cache.
Here is my controller code(show method):
if request.format == 'pdf'
render pdf: #design.slug, layout: 'application'
else
**expire_fragment('design_printed_by')**
#design.add_evaluation(:viewed_count, 1, current_user) if current_user && !current_user.evaluated?(#design, :viewed_count)
respond_with #design
end
And here is my view file code(show.html.slim) :
- cache ['design_printed_by', #design], skip_digest: true do
= render partial: 'printed_by', locals: { design: #design }
But when i add new record, this record is not display on page.
I don't know what i am missing.
Is there anything wrong with this code?
Check this link may it help you.
http://guides.rubyonrails.org/caching_with_rails.html#fragment-caching
I have been struggling with this for a while. As well as some specific help I would be grateful for some pointers how I may fill some of the gaps in my knowledge. BTW I am new to Rails and web development.
I have used DataTables to display a table records and have some code which shows me the id of the row selected by the user. From within my index view I want to use that row id to load the edit view for that data row. My .js code is as follows:
$(document).ready(function() {
/* Init the table */
TableTools.DEFAULTS.aButtons = [];
oTable = $("#highways").dataTable({
sPaginationType: "full_numbers",
bJQueryUI: true,
"bProcessing": true,
"bServerSide": true,
iDisplayLength: 25,
sAjaxSource: $('#highways').data('source'),
"aoColumns": [
null,
null,
null,
null,
null
],
"sDom": 'T<"clear">lfrtip',
"oTableTools": {
"sRowSelect": "single",
"fnRowSelected": function ( node ) {
var oTT = TableTools.fnGetInstance('highways');
var aData = oTT.fnGetSelectedData();
var n = '/highways/' + aData[0][4] + '/edit'
alert(n);
var jqxhr = $.get(n, function() {
alert("success");
})
}
},
});
} );
The development log shows:
Started GET "/highways/8/edit" for 127.0.0.1 at 2012-08-21 07:57:14 +1000
Processing by HighwaysController#edit as /
Parameters: {"id"=>"8"}
[1m[35mHighway Load (0.3ms)[0m SELECT highways.* FROM highways WHERE highways.id >= 8 LIMIT 1
Highway BARKLY HIGHWAY
Rendered highways/_form.html.erb (67.1ms)
Rendered highways/edit.html.erb within layouts/highways (258.5ms)
Completed 200 OK in 276ms (Views: 274.6ms | ActiveRecord: 0.3ms)
I have tried various things in the controller code, and in some cases the log says the edit view has been renedered but it does not show in the browser. Current controller code:
class HighwaysController < ApplicationController
respond_to :html, :json
def index
# #highways = Highway.all
# logger.debug "Highway Count: #{#highways.size}"
respond_to do |format|
format.html
format.json { render json: HighwaysDatatable.new(view_context) }
end
end
def edit
# logger.debug "Edit (render :layout => false) Highway ID #{params[:id]}"
#highway = Highway.find(params[:id])
logger.debug "Highway #{#highway.name}"
# render
respond_to do |format|
format.html
format.json { render json: HighwaysDatatable.edit(view_context) }
end
Is the $.get returning JSON ?
I have also tried a different approach. I have a link_to in the index view:
<div id ="highway_edit" >
<% #n = 11.to_s %>
<%= link_to "Edit 2", edit_highway_path(#n), :remote => true %>
</div>
This hard coded version works but I could not find a way to modify that link from within the javascript code so that it reflected the selected row id, or to call a function which would return the row id into the variable #n.
I realize that there must be some fundamentals I am missing so some suggested starting points for my education would be appreciated. I have read many other related questions but do not have enough knowledge to extract what I need.
PS I see that DataTables has an Editor feature which does pretty much what I want to achieve in the long run, but it is not 'Rails ready'.
Thanks!
EDIT:
In preparing this question I did not properly restore my code to the stage I wanted to discuss. So I have changed the controller code and the subsequent development log. So instead of a template error the problem is that the view is not rendered.
EDIT
I have proceeded with this problem and now have a result. I added a new div (class of 'result') to the top of my index view and changed my js code as follows:
var n = '/highways/' + aData[0][4] + '/edit'
$.get(n, function(data) {
$('.result').html(data);
and the edit view is rendered in that div. The result is ugly as it pushes the table down and doubles up the DataTable headers and footer. But at least it renders. I don't understand why this works when both ways go via the Edit method in the controller. I can now work on the cosmetics, or better still have the edit view appear as a modal overlay.
I would prefer to be able to click (or preferably double-click) a row and the edit view for that row be loaded. I will continue to look to do it that way. In the meantime I have added a link to the view:
<div id="EditLink">
<%= link_to "Edit Highway", :controller => :highways, :action => :edit, :id => 1 %>
</div>
and have the following code in the call back function:
"oTableTools": {
"sRowSelect": "single",
"fnRowSelected": function(node) {
var oTT = TableTools.fnGetInstance('highways');
var aData = oTT.fnGetSelectedData();
$("div#EditLink a").attr('href','/highways/' + aData[0][4] + '/edit')
}
},
which modifies the link based on the id of the selected row. Using this method the user has to know to first select a row and then click the link. If they do not first select a row they will go to the default (id = 1). You have to make sure that such an id exists in the table.
Can anyone point me in the right direction to learn about how I could implement a system similar to facebook's "like" or Twitter's "Follow/Unfollow" system that I could create in Rails?
From what I understand I would need to use Unobtrusive Javascript.
I have a Thing model(has_many :likes) and a Like model (belongs_to :thing)
Any pointers?
You can do ajax call to a function and implement whatever functionality you like inside that function , (in this case "follow" ), you can do it with :
[link_to_function][1]
Incase , you are using rails 3.2.4 and it deprecated, you can use(This is from jeremy's comment.
https://gist.github.com/rails/rails/pull/5922#issuecomment-5770442 ):
module LinkToFunctionHelper
def link_to_function(name, *args, &block)
html_options = args.extract_options!.symbolize_keys
function = block_given? ? update_page(&block) : args[0] || ''
onclick = "#{"#{html_options[:onclick]}; " if html_options[:onclick]}#{function}; return false;"
href = html_options[:href] || '#'
content_tag(:a, name, html_options.merge(:href => href, :onclick => onclick))
end
end
I am trying to write api code that utilizes the JSON rendered from the controller. I was able to successfully get my desired results locally, but when I push to Heroku parts of my JSON is not rendered correctly.
To put in context, I am trying to create a nested JSON with meal information (name, id, etc) and photo urls. Locally the photo urls render correctly in the JSON. However, on Heroku the photo urls show up as null. On Heroku, I have also tested just rendering the url JSON alone and it is getting the urls correctly.
If you know why it is rendering correctly locally and not on Heroku please let me know. Thank you
I create my JSON the following way:
def api
#meals = Meal.all
#urls = Hash.new
#return_val = Array.new
#sorted_meals = Meal.select('meals.name as meal_name, meals.id as meal_id,
COALESCE(sum(meal_ratings.rating), 0) as meal_rating,
restaurants.id as restaurant_id, restaurants.name as restaurant_name').
joins('LEFT JOIN meal_ratings ON meals.id = meal_ratings.meal_id
LEFT JOIN restaurants ON restaurants.id = meals.restaurant_id').
group('meals.name, meals.id, restaurants.id, restaurants.name').
order('meal_rating DESC').all
#meals.each do |meal|
unless meal.meal_photos.empty?
#urls[meal.id] = {"thumb" => meal.meal_photos[0].photo.url(:thumb), "profile" => meal.meal_photos[0].photo.url(:profile)}
end
end
#sorted_meals.each do |meal|
#return_val.push("id" => meal.meal_id, "name" => meal.meal_name,
"rating" => meal.meal_rating, "restaurant" => meal.restaurant_name,
"restaurant_id" => meal.restaurant_id, "urls" => #urls[meal.meal_id])
end
respond_to do |format|
format.html # show.html.erb
format.json { render json: #return_val } # render json: #url render json: #meals
end
end
The problem was due to Postgres. When I query for a meal_id it returned a string and was not working as a hash key, so I was getting nil. After turning the id string into turn an int everything worked fine. Thanks to the help of Sena this has been resolved.
I am thinking about question in routing... I have for example following in URL:
example.com/john
and for this URL I did this in routes
match "*a" => "people#person"
and in controller
def profile
#I have "john" in params[:a] variable
...
end
And know I am thinking, how to do following URL
example.com/john/something
How I should edit my routes and my controller for this shape of URL. I am newbie in Rails, and a bit confused yet in routing...
Thank you
match ":a(/:b)" => "people#person"
# controller
def person
a = params[:a]
b = params[:b]
end