Is it possible to have rails render html into a hash instead of to the client?
Something like this:
#obj = {
"foo" => Bar.find(1)
"html" => (render :partial => "yatzhee")
}
render :json => #obj.to_json
render_to_string takes all the same arguments as render but returns a string. You can then put that in a hash or do anything you want with that.
I never saw anything like that.
If you want to render json, you should really take a look at jbuilder. It's a joy to work with and it's the 'rails way' (~ it's merely built-in).
It allows you to render partials, for instance:
json.partial! "api/comments/comments", #message.comments
Related
I'm new to Ruby and Rails. I just completed a course in Laravel, so I am aware of the MVC system(not a newbie as far as the basic concepts are concerned).
I have a rather simple question,
I am sending a POST request to my RAILS REST API,the body of the post request contains a json encoded string like this--->
Array ( [method] => POST [timeout] => 45 [redirection] => 5 [httpversion] => 1.0 [blocking] => 1 [headers] => Array ( ) [body] => {"post_content":"here is the post","post_title":"here we are ","post_author":"1"} [cookies] => Array ( ) )
As you can see,its coming from my php based blog.
My rails API is supposed to be taking the post content and automatically adding links to certains words, by comparing the words with some stuff that i have in an SQLite database.
Ok, so my problem is this:
I just want the response from the Rails controller, I dont want anything loaded into a view. The Rails Controller - returns the content, with 'a href' tags around words that are found in my database. This is to be sent back as the response to my post request, and i want to access it directly as the body of the response.
As of now I dont know how this is to be done. Laravel has the ability to 'return' whatever you want to , at the end of the Controller Action, but in Rails, everything seems to want to load into a view.
I have researched some questions here and found one which said 'render :nothing => true',but that renders nothing at all.Here is what my code looks like.
def process
content = params['post_content']
##perform db function and get back the content with the links embedded.
##HOW TO RETURN THIS CONTENT.
end
Personally, I think, i have to use the render_to_string method, but I have no idea how to do this.
Any help is appreciated.
Best Regards,
Richard Madson.
Some options to consider:
Render just the raw string as the http response body:
render :text => content
Render a view without the default surrounding layout:
render :layout => false
In that case your view could just be:
<%= #content %>
Or render the content as json:
render :json => { :content => content }
The question is, what do you want returned? Text? XML? JSON?
I'm going to assume you want JSON back based on the JSON going in.
respond_to do |format|
format.json { render json: #someobject }
end
It might be helpful to see the rest of the controller method.
If I understand correctly believe what you are looking for is
render :text => "response"
there is also - JSON, XML, nothing, js, file, etc - more information here http://guides.rubyonrails.org/layouts_and_rendering.html
def list
#rings = Ring.order("RAND()")
#JSON RENDERING
render :json => #rings.to_json(:include => [:variations, :stones]), :callback => params[:callback]
end
def show
#showring = Ring.includes(:stones, :variations).find(params[:id])
#other_rings = Ring.select([:id, :stone_count]).where(:style_number => #showring.style_number).reject{ |ring| ring == #showring}
#JSON RENDERING
render :json => {#showring.to_json(:include =>[:variations, :stones]), :other_rings => #other_rings}, :callback => params[:callback]
end
My list view rendering works fine, but when i want to do a show view, with two objects, and showring with includes won't render proper JSON. It is quoting everything in the object with the includes...
JSON output looks like this:
showring => "{"available":"yes","eng...9","stone_y":"149.4"}]}"
other_rings => properly rendered object
On a seperate note, if i have already added the includes to #rings object, why do i then again have to add the association in the "to_json" method?
When you do
render :json => {:show_ring => #showring.to_json(:include =>[:variations, :stones]), :other_rings => #other_rings}
Rails is converting #showring to json (ie getting back a string representation), i.e. the value is the string literal. Instead do
render :json => {:show_ring => #showring.as_json(:include =>[:variations, :stones]), :other_rings => #other_rings}
as_json does all the work of turning the object into a hash but without the final step of turning into a string
if you are going to invest more time in building more JSON objects, you should look into a gem called rabl. It makes building JSON very simple, good for customization which then is good for building API.
I want to render an HTML-EMail and send it to our customers using some ERB Templates.
The basic code I am using:
ERB.new("newsletter.html.erb").result(binding)
doesn't allow me to add partials to the html.erb-File. I would love to move the header and footer to a partial and use the render :partial-Method in that call.
Is this possible? What do I have to add?
This is what I came up with:
viewer = ActionView::Base.new(File.join(Rails::Configuration.new.view_path, "PATH/TO/PARTIALS"))
html = viewer.render(
:file => "PATH/TO/FILE.ERB),
:locals => {:variable => #var}
)
please correct me if there is a more elegant solution than this.
I heard that HAML has a capture function that can do something like Ruby on Rails's render_to_string, but can't find info on it. Actually, in View, we can use aString = render :partial ... and render actually works the same as render_to_string (as on Rail 2.2.2). But is there also an HAML way of doing it by capture?
Yes, you can capture the Haml buffer with capture_haml. You have to include Haml::Helpers in order to use it.
However, I am not sure if it works for capturing partials. From my understanding, I'd say that Haml is independent from render and thus, render_to_string or render :partial should also work for Haml.
At least, the following will work:
str = capture_haml do
haml_tag "p#feedback.success", "Your request has been successful."
end
str # => "<p id='feedback' class='success'>Your request has been successful.</p>"
I have a controller method that returns a list for a drop down that gets rendered in a partial, but depending on where the partial is being used, the RJS template needs to be different. Can I pass a parameter to the controller that will determine which RJS gets used?
Here is the controller method, it is very simple:
def services
respond_to do |format|
format.js {
#type = HospitalCriteria.find_by_id(params[:type_id])
#services = #type.children.all
}
end
end
And here is the rjs template the gets rendered automatically
page.replace_html 'select_service', :partial => 'hospital/services'
page.replace_html 'select_condition', :partial => 'hospital/conditions'
page.replace_html 'select_procedure', :partial => 'hospital/procedures'
page << 'if ($("chosenType") != null) {'
page.replace_html 'chosenType', #type.name
page.replace_html 'chosenService', 'Selected Service'
page.replace_html 'chosenCondition', 'Selected Condition'
page.replace_html 'chosenProcedure', 'Selected Procedure'
page << '}'
I like Mike's response, but something to think about here from a design perspective:
It sounds to me like this should be in the view layer - if the action is semantically the same, but the presentation is different, perhaps having two different rjs partials and doing something like below is more compliant with MVC?
if params[:use_alternate]
render :partial => "case_1.rjs"
else
render :partial => "case_2.rjs"
end
What about placing the conditional logic in one rjs template?
# services.rjs
if #type == "your conditions"
# your rjs updates
else
# your other rjs updates
end
This gives you a cleaner controller and saves you the headache of maintaining multiple rjs templates.
something like:
if params[:use_alternate]
render :template => alternate.rjs and return
end
To keep things clean, I'd have two controller methods that render the two different RJSs. I'd then set #type and #services in a common protected method that the two controller methods call.
In my mind you are asking for something different in each case so call a different controller method. Passing in a flag to change the way the method works is just a hack and won't scale well when you have 3, 4 or 5 places. Even though you'll generate more code, it will be easier to maintain.