Basic question on Ruby Rails - ruby-on-rails

Suppose I have model xyz.rb and model abc.rb. No relation between them. If want to print any attribute from xyz in abc views/print/show.html.erb how??
I know very basic but looking for good explanation.

You can access any model from any controller, view or helper method. Mvc means model, controllers and views are related but there's no limitation on access between them. The normal thing to do would be to store the reports to an instance variable in any controller then output them in the view:
#print_controller.rb
def show
#reports = Report.find_by_some_attribute(...
#show.html.erb
<%- #reports.each do |report| -%>
<%= report.created_at -%>
<%- end -%>
I really think though that you need to find a better approach to learning rails. This is very basic like you say and I would recommend you buy a book. Do you speak English well, or what's your native language?

Something like:
XYZ.all.each do |xyz|
some(xyz)
end
Details you can find here.

Sure you can.
Assuming #x is an instance of Xyz model, you can do print any attribute of #x object.
If you dont have #x object. You can find it and instantiate #x in the show action of the abc controller. #x = Xyz.first for example.

Considering your example, if you have two models User and Report. You can access Report's created_at from User's controller,view,etc.
You need to write something like this:
Report.find_by_created_at("2013-11-12 14:43:44.11824")
You can refer ruby on rails guides to learn rails. Also you can find basic active record explanations here

This very basic but i am giving best solution to this
in abc controller
def show
#reports = Report.where(:attribute => value)
end
it will get the all records basic on that value
<h1>views/abc/show.html.erb</h1>
<% #reports.each do |report| %>
<%= report.attribute_name %>
<%end%>

Related

Rails Check if User Id is in Array

I'm trying to build a condition based on wether or not a "user" is a "member". Basically I need a way of checking if the current_user.id matches any of the user_id of any members. The non-working code I have right now is:
<% if current_user = #page.members %>
you can view this content.
<% end %>
I'm looking for something along the lines of: "If current_user.id exists in the "user_id" of any members."
Something like this, based on the field names in your question:
<% if #page.members.map(&:user_id).include? current_user.id %>
You can view this content
<% end %>
Assuming your #page.members variable contains an array, you can use the include? method:
<% if #page.members.include? current_user %>
you can view this content.
<% end %>
If you're using an array of ids, you will of course need to change the test slightly to look for the current user's id:
<% if #page.members.include? current_user.id %>
you can view this content.
<% end %>
#member_ids = #page.members.map{|m| m.id()}
then check for the condition as below
#memeber_ids.include? current_user.id()
Has said before include? should do the thing.
I'm just answering to tell you about a gem called CanCan, that gives you easy access for authorization "helpers".
Why you should use CanCan instead of doing what you are actually doing?
Don't reinventing the weel most of the times it's a goob practice.
You are placing business logic on the view (bad practice).
CanCan most likely has been developed thinking on security, and all the best practices in mind.
You save some developing hours.
Sorry if I repeated myself.

undefined method `to_key' for -- NOT USING MONGO

I found a gazillion answers for my issue if I was using Mongo, but none of the ones I see work out here since I am not using mongo.
Basically I have a report_controller.rb that has a very simple method defined:
def donations_by_season
#donations = Donation
end
and a very simple report/donations_by_season.html.erb as follows:
<%= form_for #donations do |f| %>
Stuff Will go here... such as fields to select a date for the season we wish to view.
<% end %>
There is no report model, just a controller and views.
But when I attempt to view /reports/donations_by_season
I immediately get:
undefined method to_key' for #<Class:0x00000114d85918>
What should I do to fix that? Am I doing my form incorrectly since there is no model associated with reports?
You should never be assigning an instance variable to point to a class object like this. You probably want this:
def donations_by_season
#donations = Donation.all
end
Note the .all versus just leaving it blank. You could also do .new or a litany of other methods, depending on what you're trying to do.

What's happening when Ruby shows something like this: #<Role:0x11157b630>?

I remember coming across this when first watching some Ruby videos, but I can't find it again. When Ruby shows something like this:
#<Role:0x11157b630>
,what is going on?
I have three roles (admin/staff/client) and I would like to show one of these, not
#<Role:0x11157b630>.
Any idea how I could do that?
Cheers!
What you're seeing is just a representation of the instance you've got. Say you have a title attribute on the class Role, you could, instead of logger.debug #role do something like logger.debug #role.title. If you want just doing logger.debug #role to print out something more useful, define a to_s method on Role.
Appending an inspect method should show some more details.
#role.inspect
That's what the default implementation of to_s looks like; class name followed by memory location. You can define your own version if you like:
def to_s
"My name is #{#name}"
end
When I started with rails I had strange bugs sometimes when I made something simple like:
<% #posts.each do |post| %>
....
<% end %>
I would get those strange outputs under the list of posts.
For example:
#<Post:0x11157b630>#<Post:0x11157b630>#<Post:0x11157b630>
Turns out I accidentally put a "=" in there before the loop.
<%= #posts.each do |post| %>
....
<% end %>
According to The Secret of Object#to_s, the number in #<Role:0x11157b630> is double the object's object_id in hexidecimal.

How to make the view simpler, the controller more useful?

This question relates to cleaning up the view and giving the controller more of the work.
I have many cases in my project where I have nested variables being displayed in my view. For example:
# controller
#customers = Customer.find_all_by_active(true)
render :layout => 'forms'
# view
<% #customers.each do |c| %>
<%= c.name %>
<% #orders = c.orders %> # I often end up defining nested variables inside the view
<% #orders.each do |o| %>
...
<% end %>
<% end %>
I am fairly new to RoR but it seems that what I'm doing here is at odds with the 'intelligent controller, dumb view' mentality. Where I have many customers, each with many orders, how can I define these variables properly inside my controller and then access them inside the view?
If you could provide an example of how the controller would look and then how I would relate to that in the view it would be incredibly helpful. Thank you very much!
I don't think there is anything drastically wrong with what you're doing. Looping through the customers and outputting some of their attributes and for each customer, looping through their orders and outputting some attributes is very much a view-oriented operation.
In the MVC architecture, the controller has responsibility for interacting with the model, selecting the view and (certainly in the case of Rails) providing the view with the information it needs to render the model.
You might consider extracting the code into a view helper though, if you have that exact code repeated more than once. You could even genericize it, passing in the name of a model and association. I haven't tested it, but you should be able to do something like this:
def display_attributes(models, association, attribute, association_attribute)
content = ''
models.each do |m|
content << "<p>#{m.attribute}</p>"
associated_models = m.association
associated_models.each do |am|
content << "<p>#{am.association_attribute}</p>"
end
end
content
end
Then in the view, you could use the helper like this:
<%= display_attributes(#customers, orders, name, name) %>
Obviously you would change the HTML markup within the helper method to suit your requirements. Note that if you're not using Rails 3 then you'll want to escape the output of the attribute names in the helper method.
I don't think there's anything wrong with your code. I'd just suggest for you to use a :include in your find
#customers = Customer.find_all_by_active(true, :include => :orders)
to reduce the number of queries.
I see nothing wrong with the code as you showed.
You are mixed up about the "intelligent controller, dumb view" approach though, i tend to prefer the "skinny controller, fat model", so indeed the view should be dumb, but you put the intelligence inside your model, and your helpers (or use a presenter), but definitely not in the controller.

Rails: How to store form params in a non-active record model?

I want to do store the parameters from a form in a model. Since I don't want the model to use any database, it does not inherit from ActiveRecord::Base. I'm thinking it should look something like this:
# in view:
<% form_for :question, :url => {:action => "ask"} do |f| %>
<%= f.text_field(:q) %>
<%= submit_tag %>
<% end %>
# in controller:
def ask
# I want this to magically set all variables in #question using
# values from params.
#question = params[:question]
end
# in model:
class Question
attr_accessor :q
def initialize
#q = ""
end
end
But after spending 1½ days on it, it doesn't seem to be the right way to do it. Any suggestions would be much appreciated.
Take a look at this article:
http://pullmonkey.com/2008/1/6/convert-a-ruby-hash-into-a-class-object
It shows how to create a class that will dynamically create a class from the passed in Hash.
Even if you set your Question properly, how do you plan to persist this? A file?
I think it is a much better approach to get a deep understanding of ActiveRecord before going for fancy models that have custom persistence
You might want to check out Ryan Bates' Railscast on creating a non ActiveRecord model
http://railscasts.com/episodes/121-non-active-record-model
... however I'd suggest that if you're thinking RESTfully about this, it sounds from your comment to Sam's answer like you may have another RESTful resource at work - i.e. you don't actually want to use a QuestionsController... but instead something to do with what you're actually creating (the method call you mention). You can still initialize your Question object as part of that process.

Resources