Calling Rails helper from rabl Rails - ruby-on-rails

I'm trying to call a Rails helper from my rabl template, but it's not working.
I have an image object and I want to pass its pass through my api. So then image path should have the full url (Ex: http://<my url>/uploads/myimage.jpg). The host part I want to add through a Rails helper.
#my rabl file
object #image
attributes :id, :picture_url
What I want is something like (I tried this but doesn't work)
#my rabl file
object #image
attributes :id, full_url(:picture_url)
#app/helpers/application_helper.rb
module ApplicationHelper
def full_url(path)
"#{request.host}#{path}" #something like this
end
end
But when I do this, it completely drop the :picture_url attribute from the json object

I believe this might work for you:
object #image
attributes :id
node(:picture_url) { full_url(:picture_url) }
node allows you to define things that do not directly map to object attributes.
EDIT 1
It looks like I got the node syntax wrong. Try this instead:
node(:picture_url) { |i| full_url(i.picture_url) }

By calling full_url(:picture_url), attributes gets a string that doesn't correspond to a method on the #image object, i.e., #image.id returns something, while #image.http://... isn't even valid :).
I would suggest you leave the view as it was first, and set the value of the #image.picture_url using your helper in the controller.

Related

ruby code is showing as html in template

I have a rails app which uses angularjs. Here I'm trying to render a template from rails controller and pass a resource to the template. But the ruby code for displaying the variables are showing exactly as it is in the html.erb view.
def fail
#order = Order.find(1)
render 'payments/fail'
end
in view
<%= #order.as_json %>
My guess would be that the problem is in the name of your view file. I'd guess that you named it something like fail.html instead of fail.html.erb. Without the .erb suffix, Rails just interprets the file as html text and renders it without interpreting the ruby code.
However, changing the file name isn't quite the correct solution. Since you want to render json instead of HTML you don't need to create a view template, so you should just delete the template file altogether.
All Rails models have an .as_json method automatically, so you can simply modify your controller's fail method like so:
def fail
#order = Order.find(1)
render json: #order.as_json
end
Also if you want to do something fancy and modify the json that is returned, you can define your own as_json method inside the model.

Calling Rails helper inside a rabl collection

I want to call a Rails helper method from my rabl template. I was able to it via Stack Overflow for one object.
This is my current setup (and it's working fine)
I have a helper
#app/helpers/application_helper.rb
module ApplicationHelper
def full_url(image)
"#{request.protocol}#{request.host_with_port}#{image.picture_url}" if recipe.image
end
end
#app/images/show.rabl
object #image
attributes :id, :picture_url
node(:picture_url) { full_url(#image) }
Now I want to do this for a list of image objects, but its not working and I cannot find it in rabl README.
The problem is it passes the #images list , I'm not sure how to call an the helper method on each individual object
#app/images/index.rabl
collection #images
attributes :id,
node(:picture_url) { full_url(#images) }
You can pass a param to your node block:
collection #images
attributes :id, :picture_url
node(:picture_url) {|image| full_url(image) }

Affecting resulting params set from form_for

Relative newbie here to Ruby on Rails.
Using the standard form_for method in the view for my SomeobjController#new action
= form_for #someobj do |f|
.
.
.
%p.submits
= f.submit "Submit", :class => "submit"
a submission param[] array is produced that contains a hash of #someobj for all the fields set in the form, such that
param[someobj] => { "field1" => "val1", "field2" => "val2", ... }
I would prefer to put a different value, the result of someobj.to_s to param[someobj] for the SomeobjController#create to work with, such that
param[someobj] => "strvalfromtos"
I doubt it's relative, but just in case, the model underlying this #new action is not persistent in the database (i.e., Someobj is not derived from ActiveRecord::Base, though some portions of ActiveModel are included.)
I haven't had luck trying to adjust this until after #create is invoked, but its the submission from #new to #create that I want to amend. It's not clear to me if I should be focusing more on the form_for statement or doing something special in the controller (I'm guessing the form_for is the right focus).
And, yes, this whole thing is probably a bit OCD of me, but the actual fieldnames are long (appropriately for the model) but data needed by #create is very small.
Is there a relatively painless way to do this, assuming that someobj.to_s has already been written?
Many thanks,
Richard
Change
When you submit the form, your controller will receive the params hash, as you've stated (Rails params explained?)
That means you can change any value in the hash that you wish:
def create
#has access to the params hash
params[:owner][:key] = value
end
As the create method receives the hash object, you'll have to change it in here. But because it's a standard hash (which has already been declared), you should be able to alter it as required
Add
If you want to add values to the params hash, you can use the .merge method, like this:
def create
#has access to the params hash
params[:key].merge(user_id: current_user.id)
end

Adding a hidden input field to all the forms in rails

Is there a way to add a hidden input field to all the form that are declared in views in rails. The hidden field needs to have a value passed by a public property in the controller. Essentially I want any form that is given as response by the web server to have an additional hidden input element.
How I do this? Can I override the form_for by some means ? Or can I go with a wrapper of form in partials and enforce everybody to use the partial?
EDIT: OK, my first pass on this didn't work because you can't define a value in an initializer that you're later going to pass in from a controller. So you can go about this one of two ways.
You can define a CustomFormBuilder class - put it in an initializer -
class CustomFormBuilder < ActionView::Helpers::FormBuilder
def submit(value, options = {})
#template.hidden_field_tag(options.delete(:custom_param)) + super
end
end
Then pass the :builder option to form_for
form_for #whatever, builder: CustomFormBuilder
and assuming you call submit(value, options) in the form, where options includes your custom_param, it will be overwritten by the custom method that inserts your hidden field with the value you want.
The alternative is to monkey patch monkey patch FormTagHelper instead:
module ActionView::Helpers::FormTagHelper
def extra_tags_for_form_with_custom_param(html_options)
hidden_field_tag(html_options.delete('custom_param') +
extra_tags_for_form_without_custom_param(html_options)
end
alias_method_chain :extra_tags_for_form, :custom_param
end
That's tweaking the code form_for uses to insert the authenticity token at the top of every form. Now you can pass that custom param to form_for after setting it as an instance variable in the controller:
form_for #object, custom_param: #custom_param do |f|
If you are using Ruby 2.0+ then you can use module prepend instead of the deprecated alias_method_chain e.g.
module CustomParamFormPatch
private
def extra_tags_for_form(html_options)
hidden_field_tag(html_options.delete('custom_param')) +
super
end
end
ActionView::Base.prepend(CustomParamFormPatch)

How does one add RedCloth to a form_for?

An embaressing question, but I can't seem to translate the documentation to an actual form_for. This is all the site provides..
RedCloth.new("Some text").to_html
#=> "<p>Some text</p>"
I get that that's how I parse it after its been saved. But how do I save it as marked up text?
Here's my attempt at beginning this, but I don't know how to set the parameter to save the textarea as RedCloth. Any ideas?
- form_for #text do |f|
# some RedCloth instantiation
f.submit
You don't save the parameter parsed as RedCloth like that, nor would I recommend it. Parsing it into RedCloth will result in the original value being lost unless you stored the output in an alternate field, which is what I would recommend.
You can use a before_save in your model to parse that value and store it:
before_save :parse_text
# your model methods go here
private
def parse_text
self.parsed_text = RedCloth.new(text).to_html
end
When you want to render the parsed_text value in your view you'll have to tell Rails that it's safe by doing this:
#object.parsed_text.html_safe
However, the code contained here does not account for people mixing Markdown and HTML, so be very careful how you use it.

Resources