I am using Apotomo with Rails and I have some code that looks like this:
root.find_widget(:messages).render :state => :display
which works fine.
I would like to pass some data along with that call. How do I do that?
I imagine something like this:
root.find_widget(:messages).render :state => :display, :my_variable => its_value
and then to be able to access my_variable in the widget's display method.
Please is there a way to do this?
Thanks.
You need to use render_state that comes from Cells, upon which Apotomo is built. It can be used with arguments like this:
root.find_widget(:messages).render_state(:display, my_variable: its_value)
Related
I'm building an app where I set links dynamically through a url parameter. I can't figure out how to make the link_to work with both a dynamic link and further url parameters.
TemplateController
def next
#template = Template.find(params[:t])
end
Next View
<%= link_to "#{#template.firstpage_link}(:t => #template.id, :prt => 1)" do %><%end%>
This is what it gives me:
http://localhost:3000/role/step2_path(:t%20=%3E%20#template.id,%20:prt%20=%3E%201)
I've tried a bunch of ways and I get either errors or this link
What you seem to be shooting for is something like
<%= link_to public_send(#template.firstpage_link, :t => #template.id, :prt => 1) do %>
public_send lets you call a public method by passing in its name as a symbol or string.
However, there may be more elegant ways to achieve this with the Rails router, as #Typpex is suggesting. If nothing else, you could clean up the view a bit with something like this in a helper:
def template_path(template)
public_send(template.firstpage_link, :t => template.id, :prt => 1)
end
And then calling that from your view.
I think you are not using link_to correctly, if you look at the link_to API
You will see that the first parameter is what you would like to be displayed and the second one is the rails path. You should pass your parameter when defining the rails path (or plain url) such as
link_to "display text", "#{#template.firstpage_link}?t=#{#template.id}&prt=1"
it would be better if you could use a rails route like
template_path(#template, prt: 1)
I am having troubles with an RSPec test. The test does a PUT with some objects in the request. The controller which receives the PUT seems to be not getting the correct values
For example, 'put :update, :id => #channel.id, :channel => #channel, :tags => #tag' Then, in the Controller, when I try to use params[:tags] there is an integer in that location. A Gist with the Spec and the controller method is at https://gist.github.com/3715021
This started happening when I upgraded from Rails 3.0.13 to 3.1.8
Any idea what might be happening here and how to resolve it?
I'm assuming that #tag is an object from your Tags model. When you give Rails an object like
`get :action, :foo => foo`
or in a url helper (e.g., foo_path(foo)),
Rails will turn your object into a parameter suitable for use in a url via the #to_param method. You're probably getting an integer because Tag#to_param returns the id of the tag in your db.
It looks like your update action, by contrast, expects params[:tags] to be a hash, presumably generated from a form that includes fields for values like tags[:name].
I can't help much more without knowing more about the relevant code. But I'm guessing what you want to do is change your test to read
put :update, :id => #channel.id, :channel => #channel, :tags => { :name => 'tag' }
or something like that, mimicking the params you'd get by actually submitting the form that PUTs to your update action.
This is difficult to help you because we don't know what you're trying to do. For example, it would be helpful if you showed more of the test (for example, the values you set as your variables) and the specific results of the test.
Anyway, is the #tags variable an arel object? and if so, are you expecting the ID as the value to be passed? If not, then you probably want to specify the attribute referenced in #tags. For example, #tags.name... Or, does #tags reference a hash, itself?
I want it similar to the way Twitter handles the URLs for its tweets.
For instance, right now my URL looks like this: mydomain.com/feedbacks/1/, where feedbacks is the name of the controller.
I want it to look like: mydomain.com/username/feedbacks/1/ which is similar to Twitter's: twitter.com/username/status/:id/.
My routes.rb looks like this:
resources :users do
resources :feedbacks
end
When I have it like this, it gives me the URLs as mydomain.com/users/1/feedbacks, but I want the actual username in the URL.
How do I get that?
Thanks.
Edit 1: If you are adding another answer to this question, please make sure it addresses my comments/questions to the answer already given. Otherwise it will be redundant.
scope ":username" do
resources :feedbacks
end
From the docs:
This will provide you with URLs such as /bob/posts/1 and will allow
you to reference the username part of the path as params[:username] in
controllers, helpers and views.
UPDATE:
I have tested and confirmed the accuracy of paozac's answer. I'll clarify it a bit.
Suppose you had a #feedback object with an id of 12, and the associated user had a username of foouser. If you wanted to generate a URL to the edit page for that #feedback object, you could do the following:
edit_feedback_url(:username => #feedback.user.username, :id => #feedback)
The output would be "/foouser/feedbacks/12/edit".
# A URL to the show action could be generated like so:
feedback_url(:username => feedback.user.username, :id => feedback)
#=> "/foouser/feedbacks/12"
# New
new_feedback_url(:username => current_user.username)
#=> "/foouser/feedbacks/new"
Additionally, as noted by nathanvda in the comments, you can pass ordered arguments which will be matched with the corresponding dynamic segment. In this case, the username must be passed first, and the feedback id should be passed second, i.e.:
edit_feedback_url(#feedback.user.username, #feedback)
Also, if you need help handling the params from the controller, I suggest creating a new question specific to that.
Once you have defined the scope like dwhalen says you can generate the url like this:
feedbacks_url(:username => 'foo')
and get
http://www.example.com/foo/feedbacks
or
edit_feedback_url(:username => 'foo', :id => 1)
and get
http://www.example.com/foo/feedbacks/1/edit
How do I get a form to submit it's params in the url, such that the rendered page will contain the query (rails 2.3)?
Something like this:
example.com/search?name=john&age=25&city=atlanta
Simple, I know, but I'm not sure how to do it... :)
thanks.
This is not specific to Rails. Just set the method attribute of the form to GET.
as stated by Jimmy: make sure your form-tag looks like this:
<form method="get" .....>
If you're using routing helpers to do this use:
search_path(:name => "John", :age => 25, :city => "atlanta")
I know that it is best to keep code out of the presentation layer. But, I am wondering how much is considered "acceptable". For example I populate an html select box with this line of code.
CodesecureProject.find(:all,:order => 'name').collect {|project| [project.name, project.id] }
Right now I have this line of code embedded in the form. What I am wondering if the community thinks if this is to much code and it should be first stored in an instance variable on the controller then the variable used in the form.
I'm not going to say I'd never do it (I'd be lying) but the code example given would make me nervous. I think I'd be more inclined to deliver the data to the select box from my controller. A helper method is another option if I notice I'm doing something more than once. I'm more likely to see the duplication in the controller than across distinct views.
If I'm using the same HTML component across multiple views, then I might find myself reaching for partials or wrapping the whole thing in a custom helper: project_select() or some such.
The more I work in the MVC world the more I find myself avoiding code in views. I have a feeling that some kind of Zen mastery will be achieved if I reach the zero code state, although the value of that in anything but philosophical terms is highly debatable.
I use the following static method in a Site model to achieve something similar:
class Site
def self.select_options
Site.find(:all, :order => 'UPPER(name)').collect {|s| [s.name, s.id]}
end
def
Then in my Domain view I call:
<%= f.select :site_id, Site.select_options %>
This works really well for these circumstances.
In your instance, you might try:
class CodesecureProject
def self.select_options
CodesecureProject.find(:all, :order => 'name').collect {|p| [p.name, p.id]}
end
end
And then call it through the view with:
<%= f.select :codesecure_project_id, CodesecureProject.select_options %>
I have a lot of the same code in my projects except I try to don't do any finds. In your case I would make an named scope
named_scope :order, lambda { |order| {:order => order}}
and make the code:
CodesecureProject.order(:name).collect {|project| [project.name, project.id] }
It's a little cleaner.
If you got a lot of select boxes which need a name and an id (I sure do sometimes), you could also try making a helper that excepts a ModelName and returns the array you need.
def magic_for_select(model)
model.all.collect{|instance| [instance.name, instance.id]}
end
I would go a bit further than Maran. Generally I do the following:
Create a named_scope in the model to execute the find.
Call the named_scope from the controller and store the results in an instance variable.
Only put the instance variable in the view.
I would only use a helper if absolutely necessary. When going back over your code later, it's easier to make sense of things if you see your controller setting up the data that the view needs, rather than the view calling the helper (yet another file to look at).