Rendering a partial in an iframe in rails 3 - html

Rookie coder here... I am currently building an ecommerce site in rails. I have brands and price lists on the left hand side of the results pages, these lists are often longer than the page itself, I would therefore like to put them into scroll boxes like here
I have tried putting then into iframes, using partials, but it keeps producing different errors each time, and seems more fiddly than it should be. I have only really been able to find relevant information from dated blogs etc. The code I have tried is variations of this...
View:
<iframe src="<%= url_for :action => 'brands' %>" scrollbars="auto" name="brands"></iframe>
Controller:
def brands
render :partial => 'brands', :layout => false
end
Partial:
<ul>
<% #brands.each do |prod| %>
<li><%= link_to(strip_tags(prod[0]).html_safe + " " + "(#{prod[1]})", params.merge(:brand => "#{prod[0]}")) %></li>
<% end %>
</ul>
This seems to throw up a "Couldn't find Product with id=brand" error.
I also read that iframes may be a little old fashioned, so I am fully open to alternatives. Any help would be much appreciated!

No need to use iframes for this. You should just be rendering the partial in the view itself. And if you want scroll bars you should use CSS to make the height/width fixed and then set the overflow to scroll. Here is a link to help with that

Related

Editing comments on show.html.erb rather than redirecting to new edit.html.erb page with Ruby on Rails

Like the title says, I am created the blog application from the Rails guide and I want to be able to edit comments made on articles without redirecting to an edit.html.erb page. I want a div that was previously hidden to appear in the middle of the screen with the edit form on it and the text fields filled with the comment that is being edited. Here is an image of the div that is going to appear in the middle of the screen.
I know how to edit comments by going to edit.html.erb but not in the same page or if this is even possible.
I am not looking for help with the css or html, but if there is a way to do this with js or rails that would be awesome. Thanks in advance!
Edit: So the answer by Satendra gets the partial to show up, but the fields do not contain the original comment that I wanted to edit. How can I get the text-fields to be populated with the comment?
Follow these steps to make edit comment on same page.
Create a partial name _edit.html.erb put your edit.html.erb code there.
Create a div in middle of the screen where you want to render this partial.
<div id="edit_comment" >
</div>
put :remote => true to your edit button link.
# change your path accordingly
<%= link_to edit_comment_path(:comment_id => comment.id), :remote => true %>
The :remote => true is the most important part here, it allows the whole Ajax business in the first place.
In comment_controller.rb inside edit function change respond_to js
def edit
#comment = Comment.find(params[:id])
respond_to do |format|
format.js
end
end
Create edit.js.erb and put below code there.
$("#edit_comment").html("<%= j render(:partial => 'edit', :locals =>{ :comment => #comment }) %>");
# use comment variable in your partial as it is passed as local.
Its Done.

Using one '_form.html.erb' partial but have different elements appear for certain views

Is it possible to display certain elements within a partial for a particular view in Rails? For example I'd like the submit button's text to change depending on the view: so if I'm in the new.html.erb I'd like the submit button to appear as, <%= f.submit 'Create Account' %> and <%= f.submit 'Update Account' %> for edit.html.erb. The unconventional way would be to manually add the custom code into the each view but is there a clever way to do this in my _form.html.erb partial?
First of all, I would recommend putting it into the new and edit views. However, you can switch off of params[:action] if you want to. As in
<%= f.submit(((params[:action] == 'new') ? 'Create' : 'Update') + ' Account') %>
Use simple_form with i18n for that. SimpleForm make it automatically.
Example:
<%= simple_form_for(#message) do |f| %>
<%= f.error_notification %>
<%= f.input :title %>
<%= f.input :description %>
<%= f.button :submit, class: "btn btn-primary" %>
<% end %>
I second kdeisz's answer if your intention is to use a single partial. The line he wrote will not be necessary if you use two separate views - You can just use different names on the same button in each view without any need for conditional logic.
To answer your supplemental questions: There is a tradeoff here between future changeability and DRY code. If your new and edit needs will start to differ significantly, you will have a lot of bloated, difficult-to-change conditional logic in your partial if you use it to render major features.
If you keep the views separated, this may repeat a significant amount of code, but it will also make the individual pages easier to change; the functions of each view will be tailored very specifically to the needs of each HTTP verb.
The answer isn't to conform completely to REST or to DRY "just because", but to ask yourself what will result in more work down the road. If your new and edit pages will be basically the same but for a few very minor features, the single partial (DRY) is more practical. If you see them diverging significantly in the future, keep them separated into two views (less DRY but more changeable).
Params. Each request made to Rails will automatically include an action and a controller based on the route the user requests; for example, navigating to /foo/bar might trigger action bar for controller foo, depending on how you've set up config/routes.rb. Rails fills in params[:action] and params[:controller] with these automatically. A good explanation of how this works, and how to access path and request params, can be found here.

will_paginate rendering correct html but not displaying links

I am creating a web app in Ruby on Rails which pulls images from instagram and puts them into an array.
I have a initializer/config/will_paginate_array.rb with the line:
require "will_paginate/array"
My controller looks like this:
def index
result = []
while result.length < 100
//my logic here which adds a bunch of images to the array
result.concat(data)
end
#results = result.paginate(:page => params[:page], :per_page => 13)
end
I am using this line in my html to render the links, but the links are not showing:
<%= will_paginate #results %>
To be clear, when I inspect element the markup is there(and all the pagination links are fully functional), it just isn't rendering/showing up on the page properly for some reason, and I am fairly sure it is not my css overriding anything. The pagination div generated by will_paginate has a height and width of 0. If I manually enter the next page for example localhost:3000?=2 it still advances the page correctly.
Perhaps it is some sort of compatibility issue with will_paginate and arrays?

Rails page has wrong html

I have a link to a page in the same folder as this page on my rails site:
<%= link_to 'Special Access', 'followers/special_access' %>
However, when I go to this page it shows a different page on that url.
<p id="notice"><%= notice %></p>
<div id="sent">
<p>Your request has been sent</p>
<%= link_to 'Home', followers_path %>
</div>
I tried deleting the page that the html is from, but first of all I need that page and it also gives me an error.
I edited the controller to contain:
def special_access
format.html { redirect_to followers/special_access }
format.json { render :json => #post }
end
instead of
def show
but that still didn't solve the problem.
How do I get the right html to show up on the right page?
If you do not define a route for special_access, rails will just assume the the special_acces part in the path is the :id of the route for the show page (as the urls look like followers/:id).
So first off, in your routes.rb, find the resources :followers and replace with the following:
resources :followers do
collection do
get :special_access
end
end
And now you should best always use the rails path helpers, so your link would become
<% link_to 'Special Access', special_access_followers_path %>
Here I was assuming the special access is on the collection of the followers, if it should be on a specific follower (which seems more logical to me, but I have no idea of course), you should write
resources :followers do
member do
get :special_access
end
end
And your link would become
<% link_to 'Special Access', special_access_followers_path(#follower) %>
I am not quite sure what you want to do in your controller action, I hope you just want to render an html page (because redirecting to the same url seems silly, and your syntax is wrong there too).
Hope this helps.

Rails: Creating HTML in a Model

I have a Publication model with a has_many relationship to Contributors. In the model, I have a method that's meant to create an html-ready by line:
def authors
authors = []
Contributor.where(:publication_id => self.id).each do |author|
authors << "link_to "+author.name+", Contributor.find("+author.id.to_s+")"
end
authors.to_sentence
end
In my view, I have the following line:
by <%= #publication.authors %>
But instead of rendering links, it renders the raw code, such as:
by link_to B, Contributor.find(1)
I've tried patching this by adding .html_safe to the end of #publication.authors, but to no avail. Is there a better way to transfer these links from the model to the view?
You're pushing strings into your authors array. It looks like valid code, so running eval on it should work. (Actually author.name will probably evaluate as an undefined symbol, so scratch that.)
A better way would be to use a has_many :authors, :model => 'Contributor' relationship on your Publication model, and you can bring up your array of Contributor objects by simply calling
#publication.authors
You'd want to iterate over these in your view like so:
<% #publication.authors.each do |author| %>
<%= link_to author.name, author %>
<% end %>
Note also that if you're displaying multiple Publication objects in a view this way, you'll want to use Publication.includes(:authors) in your controller when you're retrieving them to avoid the "N+1" problem.
Now, three lines of code doesn't seem very expensive to repeat, but there are ways to DRY that without violating the MVC pattern and cluttering your model:
Place the code to print a publication's authors into a partial, and call the partial as needed.
Place the code into a helper, include the helper and call the method as needed.
Here's a snippet from the source for to_sentence (you can adapt it for your needs, I think):
case length
when 0
""
when 1
self[0].to_s.dup
when 2
"#{self[0]}#{options[:two_words_connector]}#{self[1]}"
else
"#{self[0...-1].join(options[:words_connector])}#{options[:last_word_connector]}#{self[-1]}"
end
The full source can be found here.
It looks like you are trying to use haml syntax in your line. Maybe instead of using link_to, use an html hyperlink tag itself?
That being said, why are you having a model return html?
Edit: bdares answered already with what I was trying to say