I've currently got this in my view file:
<%= "<em>(#{package.to_company})</em>" unless package.to_company.blank? %>
Is my understanding correct that I should move that to a helper?
ie.
def package_company(package)
"<em>(#{package.to_company})</em>" unless package.to_company.blank?
end
I ask because I've got a few dozen unless statements in this specific view based on if a user submits specific data or not. Seemed overkill to create a few dozen helper methods for just single unless statements.
Create this helper if you'are going to re-use this exact chunk of code many times (and stay DRY)… if you're going to use it once, you don't need an helper…
Related
I've got a form to build a Document. That form needs adjusting depending on what type of Document a user has chosen. At this point I've got a deferring kind of method in new.html.erb that goes like this:
<%= render 'form_'+#template.label.downcase.parameterize.underscore %>
Which works fine but it's kinda difficult to manage though because when new types of documents are added I need to create actual HTML files and upload them.
Is there a better way to manage this kind of form generation? A view with hundreds of if statements in it feels cumbersome too.
You can push it to document_helper or decorator like :
module DocumentHelper
def form_render
return 'form_#{type}'
end
end
I am using Ruby on Rails 3.2.2 and, since my system implementation, I would like to generate different outputs (in views) and / or to retrieve different records (in controllers) depending on the "access-er" user authorization (for instance, the authorization could depend on if the "access-ed" user is or not is the current "access-er" user).
How can I handle the situation? That is, for example in order to handle if the user is or not the current user and so to display different content, should I implement two view files and / or controller actions for each case, or should I use if else statements directly in the view file and / or in the controller action?
A cleaner approach I would suggest is to create different roles for users and group them. So for that particular group you can have a separate view files and controllers. One advantage of this approach is it will be very easy to read the code and we can easily understand the code. We get more control on the page easily without having to worry about other users. We can even avoid the need for many filters. But if there is only two type of users then it could be managed easily with if else statement, so choosing the right method will depends on the problem too.
I usually use if else statements right in the views, and render partials if there is a lot of markup between the statements to keep things clean.
That is a style choice though so if you are finding you are making massive conditionals on every page, it could be that you need to rethink your organization in the controller or even make a new resource. For simple things like adding an 'edit' or 'delete' button if the user is an admin, I would use conditionals in the view.
For .html.erb markup, you can do normal if/else blocks like this:
<% if <condition> %>
<%= render 'partial_name' %>
<% else %>
<p>Some other content</p>
<% end %>
Where condition is your condition, like for example current_user? #user
I am a rails newbie writing my first App and I am having a hard time figuring out exactly how views work. I am just trying to write a simple navigation menu that dynamically grabs the list of all my "Services" and then lists the sub-catagories "Service Offerings" under those. This navigation needs to show up on every page in my App.
I tried the following just to test if I could pull the data.
#application_helper.rb
def service_list
ServiceOffering.find(1)
end
#application.html.erb
<%= service_list.name %>
<%= yield %>
This works but I read that I should not put that sort of thing in the application_helper. I moved it to the application_controller.rb but it did not work there. I am really confused about this whole thing. Obviously, I have instance variables for #service_offering in my CRUD but they all mean different things depending on the action. I just want to define one that I can access from anywhere. I have watched and read a lot of tutorials in the past few weeks but hardly any of them touch on application wide stuff like this. I would really appreciate an easy to understand explanation of how to handle things of this nature. Thank you!
If you want to set it up in the application controller you have a couple options:
you could set it up with a helper method so
#application_controller.rb
helper_method :service_list
def service_list
ServiceOffering.find(1)
end
or you could set it up with a hook and put it into a special instance variable that will not conflict with the other ones that you have
#application_controller.rb
before_filter :service_list
def service_list
#special_service_offerice = ServiceOffering.find(1)
end
I decided to try to use the cells plugin from rails:
http://cells.rubyforge.org/community.html
given that I'm new to Ruby and very used to thinking in terms of components. Since I'm developing the app piecemeal and then putting it together piece by piece, it makes sense to think in terms of components.
So, I've been able to get cells working properly inside a single view, which calls a partial. Now, what I would like to be able to do (however, maybe my instincts need to be redirected to be more "Rails-y"), is call a single cell controller and use the parameters to render one output vs. another.
Basically, if there were a controller like:
def index
params[:responsetype]
end
def processListResponse
end
def processSearchResponse
end
And I have two different controller methods that I want to respond to based on the params response type, where I have a single template on the front end and want the inner "component" to render differently depending on what type of request is made. That allows me to reuse the same front-end code.
I suppose I could do this with an ajax call instead and just have it rerender the component on the front end, but it would be nice to have the option to do it either way and to understand how to architect Rails a bit better in the process.
It seems like there should be a "render" option from within the cells framework to render to a certain controller or view, but it's not working like I expect and I don't know if I'm even in the ballpark.
Thanks!
How would the cell know in which controller it is rendered? This would break encapsulation.
You can use #render_cell in your controller view and maybe put some decider around it? Is that what you're asking for?
when we have validate_presence_of :name in the model and then when we put in the create action that we re-render 'new', then the form_for will populate the fields, and error_messages_for 'story' will have the correct error message.
this is really great, and and the same time, this looks like magic... i found that many books don't explain how the magic occur. is it by some global variable?
when the form_for is called... is it using the #story that came back from the #story.save, instead of the #story = Story.new from the new action? so if i use :story for the form_for, the fields won't be populated on error?
sometimes i feel that i am playing magic when using Ruby on Rails, except I don't know how the magic happens... kind of like if I make the rabbit appear, but I don't know how I did it. So I really want to know the inner workings of Rails.
Yes, Rails is very magical. Unfortunately these are just things that you have to learn to live with, and once you get used to the conventions you get to use the magic to do some very complicated things with great ease.
There are three separate issues here that are relatively simple individually but look very magical when you take it all in at once. Let's break them down one by one:
When validations fail, they disallow the model object from being saved and add errors to the object.errors hash.
When you run #story.save, it kicks off all the validations. Since #story.name is blank, validates_presence_of :name adds an error to the object.
Instance variables in the controller are available to the views they render.
So, yes, it is the same #story that the view has access to - the one that is invalid and has error information attached to it.
form_for takes many forms, and the one you're using is very smart
The form_for tag in your view probably looks like this:
<%= form_for #story do |story| =>
This is a special version of form_for that infers all kinds of information from the object passed in and renders the form appropriately. #story has some of its fields populated because of the line
#story = params[:story]
in your controller, so it goes ahead and fills in those fields for you. It does some other things, too - for example, it checks #story.new_record? to see if it should use the POST HTTP method (RESTful create) or the PUT method (RESTful update).
In summary, there are lots of little bits of magic to learn, but once you do the big magic is much easier to understand. Good luck!