Link_to with a custom method and adding html options - ruby

Could anyone advise how to set out the following link_to please, i thought that any html option ( and that includes a class doesnt it?) should be in {}...
So i have this link_to at the moment
<%= link_to(#portfolio.previous_post) if #portfolio.previous_post %>
I would like to add a class of 'prev' as this has a background image within the css, rather than using text..I am unsure on where to put
:class => 'prev' or class: 'prev'
depending on preference of course
This doesn't work
<%= link_to(#portfolio.previous_post, { class: 'prev'}) if #portfolio.previous_post %>
Any help appreciated

Something like this should work:
` <% if #portfolio.previous_post %>
<%= link_to "link_name",#portfolio.previous_post, class: "prev"%>
<% end %>`
This should work as well:
` <%= link_to_if(#portfolio.previous_post, "link_name", #portfolio.previous_post,
class: "prev") %>`
Once you provide a name for the url in addition to the url, everything seems to work.

Related

Separating Ruby Code which requires a block with Partials

I want to use
<% form_tag ( <<variables from partial here>> ) do %>
on a partial; problem is on the IDE it already is trying to tell me I have invalid code; this is because the "DO" is to be paired with an "END". I cannot end on the partial itself; because there is some content after the "DO" which is on the page where the partial is called.
How do I use the form_tag in the partial while using the content I have from the page which called the partial?
Sounds like you're in a very sticky situation. This is what I think you've got from your description:
#partial_1
<% form_tag (:model_name) do %>
#partial_2
<% form_contents %>
<% end %>
#controller
#model = Model.load
render(partial1 << partial2)
You may have to correct me if I'm wrong, but is it possible instead to do this?
#controller
#model = Model.load
render(partial_1)
#partial_1
<% form_tag ... %>
<% render(partial_2) %>
<% end %>
#partial_2
<% all the form guts %>
If you're using straight ruby you're probably using the ERB library and you are binding every time, which should keep the variables live all the way through.

Clarification on accessing methods

I am having trouble accessing a method i have written in a class, the problem is im trying to access it within an instance of that class, but would appreciate someone explain in a bit more details as to why this doesn't work and things to look at to get a solution.
I have created a simple helper method to use in my view to join two attributes
class TeamMember < ActiveRecord::Base
def fullname
"#{self.forename} #{self.surname}"
end
end
Within my view (show action) I want to be able to use this method
def show
#team_member = TeamMember.find(params[:id])
end
So doing this for example gives me an undefined method
<%= link_to fullname(#team_member) %>
OR
<% #team_member.each do |t| %>
<%= link_to fullname, t %>
<% end %>
Whereas this works
<% #team_member.each do |t| %>
<%= link_to "#{t.forename} #{t.surname}", t %>
<% end %>
Could someone help to clarify this for me so that i can learn from it please
You defined fullname method in your TeamMember class, but you try to call this method with implicit receiver in view, which is ActionView::Base instance. Instead, you should use explicit receiver, which must be TeamMember instance:
<%= link_to #team_member.fullname, #team_member %>
and:
<%= link_to t.fullname, t %>

rails change path of partial collection rendering

I have an STI relationship where a conversation is composed of both messages and images.
Now when I go to render them i use:
<%= render conversation %>
which works perfect. It finds the given template for the given object and renders it.
Now for my mobile site I want to use the same thing only now it should find say:
/mobile/message/_message.html.erb
instead of
/message/_message.html.erb
So in my controller i said:
if mobile?
prepend_view_path "mobile"
end
Which does get called, and it "prepends my view path" which i can see is working when i do:
raise view_paths.inspect
However now when i do my
<%= render conversation %>
It is still looking in the default location i.e. /views/ for the partial
Well, this should work, but it is distressingly inelegant:
<% conversation.each do |c| %>
<% c_class = c.class.to_s.downcase.underscore %>
<%= render :partial => "mobile/#{c_class}/#{c_class}", :object => c %>
<% end %>

How to call an `f.action` to a custom :delete callback in an Active Admin form

In order to remove (paperclip) images from my objects, I have a custom callback (and route) defined:
ActiveAdmin.register Camping do
#...
member_action :destroy_image, :method => :delete do
camping = Camping.find(params[:id])
camping.image.destroy
redirect_to({:action => :show}, :notice => "Image deleted")
end
end
This works as expected; trough a named route destroy_image_admin_camping => /admin/campings/:id/destroy_image.
The problem is that I cannot find how to add this to the form:
ActiveAdmin.register Camping do
form do |f|
f.inputs "Camping" do
f.input :name
f.input :image
f.action :delete_image, :url => destroy_image_admin_camping_path(#camping.id), :button_html => { :method => :delete }
f.input :description
end
f.actions
end
#...
end
More detailed: I don't know how to pass the "id of the current item we are editing" into destroy_image_admin_camping_path; #camping is nil, f.camping not defined and so I don't know how to pass the item in there.
Is this the right approach? I prefer this "ajax-ish" interface over a more common checkbox-that-deletes-images-on-update, but I am not sure if this will work at all.
There's a few questions here, I'll try to address them all.
How to access the "id of the current item we are editing"
You are pretty close in looking for f.camping. What you want is f.object, so:
destroy_image_admin_camping_path(f.object.id).
NOTE: f.object.id will be nil when it's a new form (as opposed to an edit form), you'll want to check for that with unless f.object.new_record?
"Is this the right approach?"
I'm not sure, really. To me it seems like making requests without actually saving the currently rendered form could create complications, but it might turn out to be a better interface. Anyway, if you want to do the checkbox-that-deletes-images-on-update, this should help you out: Rails Paperclip how to delete attachment?.
However, if you want the ajax-ish approach I think you'll want an <a> tag styled as a button. The problem with actually using a button is that you don't want to submit the form.
Here's an example:
f.inputs do
link_to 'Delete Image', delete_image_admin_camping_path(f.object.id), class: 'button', remote: true, method: :delete
end
remote: true will make it an ajax request and ActiveAdmin gives you a pretty reasonable button class for <a> tags. Updating the interface based on success / failure is left as an exercise to the reader.
Also, you'll probably want to use erb templates for this instead of the Active Admin DSL (see http://activeadmin.info/docs/5-forms.html at the bottom).
Like this:
# app/views/admin/campings/_form.html.erb
<%= semantic_form_for [:admin, #post] do |f| %>
<%= f.inputs do %>
<%= f.input :name %>
<%= f.input :image %>
<%# Actually, you might want to check for presence of the image, I don't know Paperclip well enough to demonstrate that though %>
<% unless f.object.new_record? %>
<%= image_tag f.object.image_url %>
<%= link_to 'Delete Image', delete_image_admin_camping_path(f.object.id), class: 'button', remote: true, method: :delete %>
<% end %>
...
<% end %>
<%= f.actions %>
<% end %>

How can I use do edit-in-place on three different models from a View for a model those three belong_to?

I would like to enable edit-in-place functionality in a View that displays values from different models:
This is what I use currently and it does NOT work, but would like some alternatives:
I have a model called Campaign. In the controller, I do the following to list, in order, the three Models that belong_to a Campaign:
<% #campaign_events = campaign_events %>
<% #campaign_events.each do |campaign_event| %>
<% model_name = campaign_event.class.name.tableize.singularize %>
<p>
<%= link_to campaign_event.title, send("#{model_name}_path", campaign_event) %>
<span class='model_name'>(<%= model_name.capitalize %>)</span>
<%= campaign_event.days %> Days
</p>
<% end %>
campaign_event is a campaign_helper defined as:
module CampaignsHelper
def campaign_events
return (#campaign.calls + #campaign.emails + #campaign.letters).sort{|a,b| a.days <=> b.days}
end
end
I want to be able to click on the numerical value for Days when looking at the view/campaign/show and edit the value for :days (in this case, displayed as campaign_event.days
I'm not really sure about it, but I'll try to help... I believe something like the following may work for you:
# calls controller
in_place_edit_for :call, :days
# emails controller
in_place_edit_for :email, :days
# letters controller
in_place_edit_for :letter, :days
# campaign view
<% #campaign_events = campaign_events %>
<% #campaign_events.each do |campaign_event| %>
<% controller_name = campaign_event.class.name.tableize %>
<% model_name = controller_name.singularize %>
<p>
<%= link_to campaign_event.title,
send("#{model_name}_path", campaign_event) %>
<span class='model_name'>(<%= model_name.capitalize %>)</span>
<%= in_place_editor_field model_name, :days, {},
:url => {
:controller => controller_name,
:action => 'set_#{model_name}_title',
:id => campaign_event.id} %> Days
</p>
<% end %>
There's somethings I don't know exactly how to do:
1) in_place_editor_field model_name
I believe this won't work, but I don't know how to pass the model_name.
2) :action => 'set_#{controller_name}_title'
Not sure about it also. Just doesn't look right.
Anyway, hope it helps you... and forgive me if this is completely stupid.

Resources