Show action on XML rails - ruby-on-rails-3

When in rails i would normally save records to a model and then if i want to show that individual record i would find that record by its id like so
def show
#post = Post.find(params[:id])
end
Then in my view i can show an attribute from that record like so
<%= #post.title %>
What i want to achieve is to show individual instances of data returned from an XML document, so if the xml document was like so
<entry>
<id>xxx</id>
<updated>xxx</updated>
<category scheme="xxx" term="xxx"/>
<title type="text">xxx</title>
<link rel="xxx" type="xxx" href="xxx"/>
<link rel="xxx0gmail.com/b6ea0e8ddbc4e5"/>
<link rel="xx" type="xxx" href="xxx"/> <link rel="xx" type="axx" href="xxx"/>
<gd:email rel="xxx" address="xxx" primary="xx"/>
</entry>
How can i have an action that say if i click on a link saying "view contact" how could i show that particular record?
At the moment i view all returned records like so
<% #mycontacts.each do |c| %>
<p> Name: <%= c.xpath('xmlns:title').text %> Email: <%= c.xpath('gd:email/#address').text %> <%= link_to "Update Contact" %></p>
<% end %>
which is parsed by Nokogiri
doc = Nokogiri::XML.parse(open(url))
doc.xpath('//xmlns:feed/xmlns:entry[xmlns:title[node()]]')

You could do this by using some more xpath.
doc.xpath("//entry[id='xxx']")
This will return all the entries that have that specific ID (xxx in this case)
you can "imbed" information in a url by passing it to the link_to method
<%= link_to "show entry", :id => "xxx" %>
it will just be in the params hash
params[:id]
=> 'xxx'

Related

I am new on rails i not sure what is going on my code but I want to filter data from database by searching using id how can i do it

I am trying generate a code that tracks for documents that revolve within the organisation. I have done other codes for adding employees, adding document types and logging in now I am struggling on creating a document form and search from the document that I have created. This code is for searching:
controller#show
def show
#generate_documents = GenerateDocument.where('Reciever LIKE?',"%#{params[:search]}%")
# #generate_documents = GenerateDocument.all
end
views/show
<%= form_tag generate_document_path, :method => :get do %>
<p>
<%= text_field_tag :search, params[:search] %>
<%= submit_tag "Search" %>
</p>
<% end %>
<!-- end of seaerch form -->
<!-- loading data from database and displaying then in a list format BEGIN -->
<ul>
<% #generate_documents.each do |generate_document| %>
<li>
<%= link_to generate_document.Reciever, edit_generate_document_path(generate_document) %>
</li>
<% end %>`enter code here`
</ul>
<!--
END LISTING -->
<%= link_to 'New Generate Document', new_generate_document_path %>
Even Iam new to rails, but i can help you with basics that you need to pass the parameters from the view to the controller, therefore you can use:
:url => {:controller => "name_of_your_controller", :action => "action_to_be_perforemed", :id => "whatever id you want"}
or else you can also pass the object within the url like we do while edit request
<%= link_to "Edit", edit_post_path(#edit)%>
which will give the :id of the particular post.
Hope this may help you.

Passing an instance variable into a form - rails

This is likely an error due to my minimal understanding of Rails and how to use variables across models, so if there is more code needed to answer it or if my terminology is incorrect, let me know and I will gladly update the question.
I have a feed of posts that I want a user to be able to "like." While the following code allows likes to work on an individual post's page - site.com:3000/posts/*post.id* - with the form data being passed of like[liked_post_id]:*post.id*, when I try to submit a like on a profile - site.com:3000/users/*user.id* - which contains a feed of posts, the form data being passed is like[liked_post_id]: (blank value)
How can I pass the post's ID within a feed of posts to the liked_post_id variable in _like.html.erb?
I have noticed that the action of the like form is /likes across the board. Would this will only work when you are on the page site.com:3000/posts/*post.id*? I'm curious if I need to modify the it so that the action of the form is /posts/*post.id*/likes when you are on the page site.com:3000/users/*user.id*
From my post view:
#views/posts/_post.html.erb:
...
<%= render 'posts/like_form' if signed_in? %>
...
Route to proper form:
#views/posts/_like_form.html.erb:
<div id="like_form">
<% if current_user.likes_this?(#post) %>
<%= render "posts/unlike" %>
<% else %>
<%= render "posts/like" %>
<% end %>
</div>
Like from:
#views/posts/_like.html.erb
<%= form_for Like.new, :remote => true do |f| %>
<%= f.hidden_field :liked_post_id, :value => #post.id %>
<%= f.submit "Like" %>
<% end %>
From profile (feed of posts):
#views/users/show.html.erb
...
<%= render #posts %>
...
Likes controller:
#controllers/likes_controller.rb
class LikesController < ApplicationController
before_filter :signed_in_user
def create
#post = Post.find(params[:like][:liked_post_id])
current_user.like!(#post)
respond_to do |format|
format.html { redirect_to root_url }
format.js
end
end
...
User model:
#models/user.rb
...
def like!(post)
likes.create!(liked_post_id: post.id)
end
...
#frank-blizzard has pointed out that my form markup is an issue. On a post's page the generated markup is:
<input id="like_liked_post_id" name="like[liked_post_id]" type="hidden" value="73" />
While on the feed page:
<input id="like_liked_post_id" name="like[liked_post_id]" type="hidden" />
You can do something like this:
<% form_for Like.new, :remote => true do |f| %>
<%= f.hidden_field :post_id, :value => #post.id %>
<%= f.submit %>
<% end %>
The current_user.likes.build(...) part should get out of your view and inside your controller. You are using a current_user.like! method so I guess you have implemented already some method in user model to accomplish this. If not build your like in the create action of LikesController where you can access params[:like].
def create
#post = Post.find(params[:like][:post_id])
current_user.likes.build(#post)
# ...
end
EDiT
You might need to pass your #post variable correctly into your _like_form partials, like so:
#views/posts/_post.html.erb:
...
<% if signed_in? %>
<%= render 'posts/like_form', :post => #post %>
<% end %>
...
This will give you acceess to a post variable inside the partial so you can prepopulate your forms value with its id. See this questions as well Pass a variable into a partial, rails 3? and make sure to read up on how to pass variables correctly to partials. you can debug your views using <%= debug <variablename> %>

Rails search functionality

I am taking a rails class at my University and I am trying to create a search form which will show the results on the same page rather than show a different page of results. Is this something simple to do? I am creating a museum app with artifacts for each museum but I want the user to search artifacts from either page.
On my routes.rb I have
resources :artifacts do
collection do
get 'search'
end
end
On my museum index I have the code below that he gave us but not sure how to tweak the get routes for the same page.
<%= form_tag search_artifacts_path, :method => 'get' do %>
<p>
<%= text_field_tag :search_text, params[:search_text] %>
<%= submit_tag 'Search' %>
</p>
<% end %>
<% if #artifacts %>
<p> <%= #artifacts.length %> matching artifacts. </p>
<h2> Matching Artifacts </h2>
<% #artifacts.each do |a| %>
<%= link_to "#{a.name} (#{a.year})", a %><br />
<% end %>
<% end %>
Yes, this is easy. Just have the index page return the search results if params[:search_text] is present - this way you don't need a new route or a different page.
class ArtifactsController < ApplicationController
def index
#artifacts = Artifact.search(params[:search_text])
end
end
class Artifact < ActiveRecord::Base
def self.search(query)
if query
where('name ILIKE ?', "%#{query}%")
else
all
end
end
end
So then your form looks like:
<%= form_tag artifacts_path, :method => 'get' do %>
<p>
<%= text_field_tag :search_text, params[:search_text] %>
<%= submit_tag 'Search' %>
</p>
<% end %>
Edit:
So what you really want to do is any page you want to search, include a form which makes a request to that same page.
Then in each of those controller methods just put this line of code:
#artifacts = Artifact.search(params[:search_text])
and that will populate the #artifcats array with only artifacts that match the search query.
Try using "Ransack" gem. It can also perform some more powerful searches.

Rails: Two separate create forms..how to keep them separate?

In Rails 3.0 I have the standard 'new' form that creates a new record, in this case a patient. It works fine and the validations / error showing also work fine.
The client now wants the form in Spanish.
So, I did this:
Created a new html doc called "newspanish" (Cut / paste code from "patients/new")
Created a new partial called "_form_newspanish" and referenced it where the "form" partial is in "newspanish" (Cut / paste code from view "patients/_form")
Created a controller action in "patients" called "newspanish" and cut/pasted exact code from the "new" action.
I left the "create" action untouched.
Added match "patients/newspanish" to routes.
Translated the english parts to spanish in views/newspanish and views/_form_newspanish. Just the stuff that users read on the page, of course...not the rails code.
And, it works, for perfect submissions.
For submissions that fail validation (like putting 3 digits in as a phone number), the page reverts to the view "patients/new" and shows the errors above the form... in English, of course, because patients/new is in English.
Of course, I want it to revert to "views/newspanish" and also show custom verbage in the validations errors (spanish).
Any thoughts on how I can get the patients/newspanish view to load when error validation it tripped?
Here's my code for "_form_newspanish"
<%= form_for(#patient) do |f| %>
<% if #patient.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#patient.errors.count, "error") %> prohibited this subscriber from being saved:</h2>
<ul>
<% #patient.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<p><label for="mobile">Número de teléfono celular o móvil*</label>: <%= f.text_field :mobile %></p>
<br />
<%= f.submit "Inscribirme" %>
</div>
<% end %>
And controller... patients/newspanish
def newspanish
#patient = Patient.new
respond_to do |format|
format.html # new.html.erb
format.xml { render :xml => #patient }
end
end
<%= form_for(#patient) do |f| %>
is creating a form whose url is submits to is "/patients" which matches to patients_controller, create action.
That create action probably has a line that says (in my pseudo code)
if #patient.save
redirect to somewhere
else
render :new
end
That line "render :new" is showing the "patients/new" view.
So what you have to figure out is to either
1) detect in patients_controller # create how to tell if its spanish, and render "newspanish"
OR
2) change <%= form_for(#patient) do |f| %> to submit to a new url that just handles the spanish version, and make a new controller or action that just handles the spanish form (and renders "newspanish" if the #patient doesn't save
For #2, you could manually change where the form submits to with
<%= form_for(#patient), :url => spanish_patients_path do |f| %>
and in your routes create
post "patients/spanish" => "patients#create_in_spanish"
and add def create_in_spanish to your patients controller

Rails 3 object nil or not create

Im working on a rails app where a user has the ability to upload photos. When a user uploads their photos it will appear on their profile. Everything works great besides when there is no photos created then I am unable to view the user profile page because of the photo being nil.
here is my show method in the users_controller.rb
def show
#user = User.find_by_id(:id)
#photo = #user.photos.find(params[:id])
end
Here is my show.html.erb
<% for photo in #user.photos %>
<%= photo.title %>
<%= photo.description %>
<%= image_tag photo.image_url(:thumbnail) %>
<%= link_to "Show", photo %>
<br>
<% end %>
How can I bypass this error?
The code for your action seems wrong...
It should be this:
def show
#user = User.find(params[:id])
##photo = #user.photos.find(params[:id])
end
I commented out the third line on purpose, because I'm not sure what it is you want to do there, yet.
The #user variable needs to be defined using params[:id], given that this is the show action for the UsersController, so the id for the user will be passed through as params[:id].
But then you go and use this to find the photo for the user, which is what confuses me... the Photo record's id attribute is probably not going to be the same as the User record's id attribute.
So what is it?
You can replace the code in your show.html.erb with this:
<% if #user.photos %>
<% for photo in #user.photos %>
<%= photo.title %>
<%= photo.description %>
<%= image_tag photo.image_url(:thumbnail) %>
<%= link_to "Show", photo %>
<br>
<% end %>
<% end %>
The problem is, when the user doesn't have any photos, #user.photos returns nil so you have to check for that first.