How to render a view inside of another view (rails 4) - ruby-on-rails-4

Hi I want to preface this by saying that I am new to coding.
I have an issue that I believe can be solved in two ways
A. by rendering a partial
B. by updating the controller
( I can totally be wrong but these are what I suspect lol)
I have two controllers/views "reviews" and "logs". and I want them to both appear on the same page.
How can I do this?
I tried rendering a partial but I alway get an error.
and I tried the piece of code below:
which made my reviews show up on the page, but when I add
#log = #user.logs.all
to it, it doesn't pull all the logs to the page like it does for the reviews.
def show
#user = User.find_by_name(params[:id])
if #user
#reviews = #user.reviews.all
render action: :show
else
render file: 'public/404', status: 404, formats: [html]
end
end

First things first. Views refer to actions in controllers. So there can be several views for each controller or even none.
So, if you want to render #reviews and #logs on the same page you should first instantiate both instance variables in the same action and then render both partials in the same action.
How do you do that? Easy.
First you got to the controller you just showed and edit that show action.
def show
# You can set the variable in the if-clause
# And you also need to use static finders with a hash as an argument in Rails4
if (#user = User.find_by(name: params[:id]))
#reviews = #user.reviews.all
#logs = #user.logs.all
# You don't need to call render explicitly
# if you render the view with the same name as the action
else
render file: 'public/404', status: 404, formats: [html]
end
end
Second: you go to your /app/views/reviews/show.html.erb template and put both partials there like this (this is just an example, adjust your markup to fit your needs).
<h1> Reviews and Logs</h1>
<div id="reviews_part">
<%= render #reviews %>
</div>
<div id="logs_part">
<%= render #logs %>
</div>
Now create 2 new partials /app/views/reviews/_review.html.erb and /app/views/logs/_log.html.erb and put all the needed markup there (use regular variables review and log to adress the repeating objects). Rails will automaticaly repeat those partials as many times as needed.
Or you can explicitely call the partial render
<div id="reviews_part">
<% #reviews.each do |review| %>
<%= render review %>
which is the same as
<%= render partial:"reviews/review", locals:{review:review} %>
<% end %>
</div>

Here is the way of rendering partials into views in HAML:
=render :partial => "header"
%h2 Hello World
=render :partial => "footer"
Every partial you render this way, has to be created within the same folder.
Each partial's name has to begin with an underscore (_). This should be the view's directory:
- home
- index.html.haml
- _header.html.haml
- _footer.html.haml

Related

Rails form_for direct to index action

I have a form_for tag that I want to use the index action in the search_results controller.
My tag looks like the following.
<%=form_for(:search_results, url:{controller: :search_results, action: :index}, html:{id:"quickSearch"}) do | f| %>
...form fields...
<% end %>
However when I try to enter something into my form and submit it, it is going to the create action instead of the index action? Normally this would make sense if I didn't specify the action, but I did. I also tried removing the action and making the tag use the get method but it never hits the controller and I need it to do that.

Using hidden fields in rails views

What is the best practice using hidden fields in html views?
In my html.erb I need to check if a value exists, if it does then u want to ensure a button remains disabled.
Can I set a hidden field in ruby code like this ;
<% if #is_draft %>
<input type="hidden" id="isdraft "value="true"><% end %>
Then can I access this in my jquery code?
Is this accepted practice? Note that the javascript is in its own file, the script is not in the html.erb file
It is regarded as pretty poor practice most of the time.
Instead it is usually better to render the button as disabled on the server side after checking the condition.
Also make sure to sanitize the requests made by this form (button is clicked although your condition does not permit it). Users could un-disable the button and click it.
If you find that you have to save some information in HTML for whatever reason, I would resort to data-*-attributes!
Hope that helps!
EDIT pseudocode example:
# MyView.html.erb
<% unless #is_draft %>
<%= render partial: 'my_checkbox_button_enabling', format: [:js] %>
<% end %>
<%= button_tag "My nice button", disabled: true, id: "my-button" %>

Rails 4 search from "home page" to other models/controllers

UPDATE 4-6-2015:
Double checked here:
https://github.com/activerecord-hackery/ransack
to make sure I had everything right, aside from a few hiccups I think I do. I am not clear how or what automagic makes the f.submit whisk the user away to that model index with nothing in that model filled out, and the index action taking presidence (hence after doing a search takes me to the index view of the groups (what I am searching on) and shows everything from db as if the Group.all was called ignoring the search string (that I can see in the address bar) completely.
Really not sure what I am missing I am sure it something minusculey stupid on my part.
EDIT/UPDATE: So i got most of this working, the search screen is going to that controller. I am not sure what automagic is causing that, I thought my respond_to could trap and send back json so I could this with an ajax call and update the table that is in the main page. THEN if they click on that table it takes them to the edit form of that particular item (i.e. the edit of the correct model).
My visitor_controller.rb:
def index
#search = Group.ransack(name_cont: params[:q])
#groups = #search.result
respond_to do |format|
format.html
format.js
end
end
Adding the routes file too:
Rails.application.routes.draw do
resources :groups
get 'visitors', to: 'visitors#index'
root to: 'visitors#index'
end
So groups is a controller/model that I am trying to search on (one of many, will use the example in the answer to do many when I get the one just working first.)
So I am building an app, I found a "simple search" tutorial for rails 4:
http://www.stefanosioannou.com/rails-4-simple-search-form/
But I think that this assumes you to search from the view/model and all that of your controller. I.e.
I am in the groups view, I want to search my groups all through that controller.
Really what I am doing and finding so hard to do is have a welcome page, that has three search bars. Each bar searches a different model/view/controller.
The welcome page is called visitors and has its own controller, and view just no model.
So my visitors controller has this:
class VisitorsController < ApplicationController
def index
#groups = Group.search(params[:gsearch])
respond_to do |format|
format.html
format.js
end
end
end
I was just trying to get one search bar working for my Group model, so in my Visitors index.html.erb:
<div class="span12">
<h3>Welcome IPA of NM</h3>
<!-- search bar here -->
<% form_tag group_path, :method => 'get' do %>
<p>
<%= text_field_tag :gsearch, params[:search] %>
<%= submit_tag "Search Groups", :name => nil %>
</p>
<% end %>
</div>
This fails though as it says
No route matches {:action=>"show", :controller=>"groups"} missing required keys: [:id]
so here is my groups controller:
class GroupsController < ApplicationController
before_action :set_group, only: [:show, :edit, :update, :destroy]
def show
end
private
# Use callbacks to share common setup or constraints between actions.
def set_group
#group = Group.find(params[:id])
end
end
I am sure somehow the form code in the visitors index.html.erb is working with that group_path which means it is trying to do a show but has no ID yet when just starting? I really am lost, new to rails4 and not sure what I am missing here. I am guessing the convention is do all things from your model/view/controller not a cross views as I am trying to do here? So something I have to do extra to get around the convention or I am doing the whole thing wrong from the get go?
I would highly recommend Ransack for search queries in rails. You can view it here > https://github.com/activerecord-hackery/ransack and you can also watch an awesome rails cast by Ryan Bates over at http://railscasts.com/episodes/370-ransack
Ransack works across the board, you could even search all 3 models from the same form.
Using ransack, you would simply use:
<%= search_form_for #q do |f| %>
# Search if the models name field contains...
<%= f.label :name_cont %>
<%= f.search_field :name_cont %>
<%= f.submit %>
<% end %>
Then the search controller processes this into #results:
def index
#q = params[:q]
#search = Model.search(name_cont: #q)
#results = #search.result
end
Then you would loop through the results on your show/index page.
<% #results.each do |result| %>
<%= result.name
<% end %>
This would show all of your results on one search page. If you wanted to search multiple models, you can either have multiple forms assigning a different instance variable for each one eg: #q1 #q2 #q3 or, you could search them all from one model by using different instance variables for the search and results.eg
def index
#q = params[:q]
#firstsearch = User.search(username_cont: #q)
#secondsearch = Post.search(title_or_description_cont: #q)
#users = #firstsearch.result
#posts = #secondsearch.result
end
Remember to add the routes =)
get 'search', to: 'search#index'

How to open page as modal window in Rails 4?

I have an edit action that I would like to put on a modal window on my App, and when it's closed I need to refresh a part of my view.
Does anybody knows how can I do that using Rails 4?
Lets assume you want to open the user edit page in a modal. Here's the solution I prefer:
# Create a ajax link somewhere that opens the user modal:
<%= link_to user.name, edit_user_path(user), remote: true %>
# This link calls your controller action:
class UsersController < ApplicationController
def edit
#user = User.find(params[:id])
render_js_modal(:any_id, 'edit')
end
end
class ApplicationController
def render_js_modal(id, partial, options)
#id = id
#partial = partial
#options = options
respond_to do |format|
format.js { render 'application/render_modal' }
end
end
end
# The view depends on which CSS library you are using. This
# example is if you use semantic ui. If you use something like
# bootstrap you will probably need to create a bit more html in the JS.
# views/application/render_modal.js.erb:
$(body).append('<div id="<%= #id %>"></div>');
var element = $('#<%= #id %>');
element.html('<%= j(render partial: #partial, #options) %>');
element.modal('show');
Hope this helps. If you get any errors, remember to look in the rails server log for details. For JS details look in the browser console. Note you can pass locals to the partial in the options param. You can create many other useful methods like this:
render_js_modal_hide: hide a modal on screen by id. Useful when the user is created successfully. Consider replacing the page flash messages with the JS response as well.
render_js_content_replace: replaces a div on the page with the content of provided partial. This is useful for replacing the content of a modal if there are validation errors.
etc.
I've done this in that way (using Slim):
.text-center = link_to 'Visualizar Documentos', 'Visualizar Documentos', class: 'btn btn-default btn-primary btn-large', "data-toggle" => "modal", "data-target" => "#meioambiente"
.modal.fade id="meioambiente" tabindex="-1" role="dialog" aria-labelledby="meioambiente-label" aria-hidden="true"
And everything worked perfectly. Thanks!
Twitter Bootstrap and ZURB Foundation both have modal components. You will need to use JavaScript to update the DOM.
Codecademy is a free online learning website and have great tutorials to learn JavaScript and jQuery. I would also suggest Code School since they have a free course on JavaScript, jQuery and Angular.js.

trying to link image to specific model id in rails

I'm having a routing issue with an image. In my app I have images of items on the home page. I would like them to link to their image page.
Here is what my items controller looks like:
class ItemsController < ApplicationController
def show
#item = Item.find(params[:id])
end
end
This is what I have in my routes:
Rails.application.routes.draw do
resources :items
end
And this is what I have in the item partial:
<%= link_to(image_tag(item.image.url(:thumb)), item_path(:id)) %>
What I expected after reading the rails routing guide was that this would link to the item page for that image. Here is their example:
photo_path(:id) returns /photos/:id (for instance, photo_path(10) returns /photos/10)
I should also add that this is in my home page controller:
class StaticPagesController < ApplicationController
def home
#items = Item.where.not(category_id: 1)
end
However, that is not working. I've tried several different things, but all produce errors. Is there a simple way to do this?
The normal way to do what you want is this:
<%= link_to item_path(item) do %>
<%= image_tag(item.image.url(:thumb)) %>
<% end %>
You can just pass the instance of the item to item_path and also if you have complicated html for a link, it is usual to put it in a block for the link as shown here (with link_to something do).