I have two models and controllers:
Snippets, and Tags.
There is a belongs_to relationship, with tags belonging to snippets. This works well, I have a text field which creates a new tag associated with the snippet when the user submits a snippet.
I want to be able to have a text field which, when submitted to a function (in the model) would split the text on commas (e.g. split(",")).
However, I'm having a little trouble with it.
My though process was, def a function on the Snippet model that splits the input then loops the array of the split, creating a new Tag associated with the Snippet at save time.
Sounds easy enough, but with the RoR magic it's just not happening for me :)
Can someone shed some light / link to a document or something - would be grand!!
Using rails3 with ruby 1.9.2 - normally PHP dev but giving this ruby a go. Magic.
There is a Railscast that explains how to use a virtual attribute in your model to convert submitted "tag_names" into associated models.
It also shows how to do a has_many :through association (called "Taggings") so that tags can belong to many snippets. In your setup, a tag can only belong to one snippet, so you would likely be creating many duplicate tags, when in fact they're the same tag, just associated to different snippets.
If you prefer reading to screencasts, you can check out the transcribed ASCIIcasts.
Related
My issue is simple, lets say I have two models/tables named 'abc' and 'pqr', both has three columns as 'a','b','c' in abc and 'p','q','r' in pqr. This two models may or may not be related/nested.
what I want to do is to create a single webpage. On that webpage I want to create a single form which will submit the data for two models/table with single button. May be I will create two form but I want only one submit button. How do solve this issue in ruby on rails.
As in rails we have one model per table.
You can only use accepts_nested_attributes_for if the two models are related. Otherwise, if the models are unrelated, see Anton's answer in rails: a single simple_form with two unrelated models? describing how to use the fields_for helper to accomplish this.
I can suggest you something in Ruby side. It is possible to do that with accepts_nested_attributes_for method.
You can add to
models/abc.rb
accepts_nested_attributes_for :pqr
You can find more information about it here.
http://api.rubyonrails.org/classes/ActiveRecord/NestedAttributes/ClassMethods.html
I have a project that is built with a tagging model to reference three different models: artist, article, event. I have associated each model to the tagging model via has_many through:. I have two problems; both related to each other:
I have 5 "default" methods that I wish to be able to call restfully from the tagging controller/model: popular, upcoming, events, articles, and artists. Each method is designed to do exactly as it's name implies. The issue lies within these methods being a query by nature. How can I maintain a consistent schema where 5 of the many taggings models I have require a special attribute (let's call it content) that should subsequently call the appropriate method?
When calling any one of the taggings models, it will return (in it's content attribute) an array of the 3 models specified earlier. Other than adding a method within each model that contains a localized description of the model and then calling upon that type method to match another hardcoded string elsewhere, is there any alternative? I don't like how the implementation I just described requires me to hardcode values. Eek.
I'm very new to Ruby on Rails, so I apologize if this is an obvious solution. However I have spent a week looking into ways to solve this compound problem that I'm trying to solve. Any input is appreciated!
As far as i unterstand you need a polymorphic association. Because tags can be applied on different models, the clue is to treat all these models in polymorphic manner by marking them as :taggable on the association to tags.
I would just use the popular acts_as_taggable_on gem for it.
I'm not sure what's the best approach in my situation, I would like an opinion.
My situation is:
I have a "Ticket" model, having several fields of many kinds: text, numerical and associations. Tickets support comments through the acts_as_commentable gem.
The tickets are generated by users, who can comment and modify their own tickets.
Because the fields of a ticket can change over time I would like to allow my users to modify several of them. What I need though is to keep a commented history of all the changes, so that at any moment they can see in a ticket what, why and when was changed, in the comment, timestamp and list of changes that they can see together with the comment.
I was thinking to solve this by generating a "TicketUpdate" model, have the TicketUpdates generated in the Comments form (using fields_for and accepts_nested_attributes_for).
Basically the user could select in a drop down list (i.e. a select tag) the field they want to change, changing the value of the drop down would trigger an event to show an appropriate input field (input for the text and numeric fields, select for the associations) with the old value pre-populated
I could intercept the TicketUpdates in the "comment/create" controller performing the updates.
This approach would look nice and sweet to the user, but I don't see how to implement in a neat or DRY way.
Because ticket has many fields and they are mixed decimals and associations, I would have to implement specific logic for each field, both in the view and in the controller.
I'm not sure if there's maybe a better approach, or there's actually any gem or trick to get this done easily.
anyone got anything to recommend me here?
I'm using rails 3.2.8.
I am working at a web app in Rails that behaves much like a CMS: there are articles, which have a text attribute that contains links to other articles (or other object classes). I'm currently storing the attribute as HTML.
Is there any good way to model those links in a way that is relative easy to change, and contain the reference to the object id, instead of the absolute url?
One of the solutons I was thinking was to use some kind of special mark-up, such as:
[link_to "Text for the link", Article:12]
where 12 is the id of the article it links to. This mark-up will be parsed when the text is rendered.
The downside of this is that I have to hack into TinyMCE (the editor I'm thinking of using to edit the HTML) so that it can insert links to other objects, by accessing the database and automatically assigning the object type and ID (the person who's editing the texts doesn't know the id's).
Is there any simple solution to this?
Or should I stick to using absolute urls (which, besides maintenance issues, is annoying in development, as they will always point to production and that is confusing for me)?
Additionally, does anyone have similar examples in other languages (php, Wordpress, other CMS, etc) that tackle this problem in a nice way? I'm thinking, this is pretty vital in CMS, and can reduce a lot of man hours if a nice system can handle all those links.
EDIT:
Another possible solution that I'm thinking about is letting the person copy the link of the article directly in the code, but it should, upon submission, generate the correct association id and make it so that if the url structure changes, the link is always up-to-date. I'd like to hear your opinions and experience with this approach, if you have tried it.
The challenge with this approach is parsing the link with Rails and finding out that it points to an Article, and that article has the id ##. Then I have to insert a shortcode that will always translate, upon parsing and rendering, to an actual link to that article.
I found a method that could make this feasible:
Rails.application.routes.recognize_path
But there may be some caveats that I don't see right now...
EDIT no. 2
I also want to specify that I chose CKEditor as the content editor, but I will consider other ones if there are clearer advantages.
I have built something similar using a shortcode system which would allow me to call specific methods on the model and replace the shortcode in the text:
Helper
def parse_shortcode(model)
text = model.text
text.gsub(/(\[#!\s?\w+\])/i) do |match|
result = model.try(match)
result.nil? '' : link_to(result[:text], result[:url])
end
end
Model
def contact_link
{ :text => self.name, :url => self.url }
end
View
<%= parse_shortcode(#article) %>
I haven't tested the above code and it is obviously a bit simplified but it explains my thought process behind this.
EDIT: Just to clarify my above example uses an invented shortcode syntax of [#! method]
An article can have many related_articles and at the same time this article can be related by many other articles, so it is best to model this as a many-to-many relationship.
One way to define this type of relationship in Rails is has_many :through.
To use has_many :through you have to create a join model, perhaps call it ArticleRelation. This model will have two fields, an article_id that represents the current article and a related_article_id that represents the article who’s being referred as related.
class Article < AR::Base
has_many :article_relations
has_many :related_articles, :through => :article_relations
end
class ArticleRelation < AR::Base
belongs_to :article
belongs_to :article_relation, :class_name => 'Article'
end
When creating self-referential relationships it’s important to remember that you’re only creating one side of the relationship. Although article_1 might list article_2 as related, there is no way to for article_2 to list article_1 as related. You'd need two ArticleRelation records to create a mutual relationship.
It’s difficult to think up appropriate names to define another side of the relationship so you can prefix both with the word “inverse” to give inverse_article_relations and inverse_related_articles. You also need to specify some additional options to make the relationships work. For inverse_article_relations you’ll have to specify the name of the other model as it can’t be inferred from the relationship name and you’ll also have to define the foreign key as related_article_id. For the inverse_related_articles relationship you need to specify the source as articles, as again it cannot be inferred from the name of the relationship.
has_many :inverse_article_relations, :class_name => "ArticleRelation", :foreign_key => "related_article_id"
has_many :inverse_related_articles, :through => :inverse_article_relations, :source => :article
Test it out, this should work for you per current requirement.
A solution I've seen in a lot of other CMSs is a combination of custom file browser in TinyMCE and page rewriting (similar to freakyDaz's answer).
TinyMCE has documentation and example code for implementing a custom browser. You'll have to provide the backend pieces, of course.
CKEditor has documentation for a similar feature as well.
Have your backend implementation return something that's easy to parse for the URLs (urlfor:Article:12, for instance), then have your rendering code replace those with actual URLs.
I just thought of another possible solution for the use case:
The admin user specifies the relationships before they edit the text (using Chosen.js, this can be done in a user-friendly way).
Then the person either submits the form to save the model or it can be done asynchronously.
When the relationships are saved, a shortcode is generated and displayed for each of them, and that short-code can easily be pasted in the text.
When displaying the text in the front-end, the text will be parsed for the shortcode, in a similar way to what #freakyDaz is suggesting.
In this way, I don't have to hack or create custom actions in the editor. I think it's a pretty pragmatical approach, but I'd like to hear your opinions. Of course, the admin who's making the text should be educated to follow the process in that order, but in my case very few persons can be admins (1 or 2), so it's manageable.
Is it possible to use select fields with nested object forms feature of Rails 2.3?
Example:
Suppose you have a Article model, Category model, and a ArticleCategories join model. Article has_many Categories through ArticleCategories.
On our Edit Article form, you want to have an HTML select list of all the available categories. The user can select one or more Category names to assign to the Article (multiple select is enabled).
There are lots of ways to do this, but I'm wondering if there is a simple way to accomplish this using the nested objects feature. What would the form look like in your view?
Check out the nested form example from Github:
http://github.com/alloy/complex-form-examples
It's been a while since I looked at it, so I'm not sure if it covers exactly what you wanna do, but its a nice source for ideas / patterns.
Assuming you have defined the models and their relationships so you can do this:
#art = Article.find(article_id)
#art.categories # returns list of category objects this article is assigned to.
Then I usually use http://trendwork.kmf.de/175
You need to copy the JavaScript file into public/javascripts but after that you can just create the form element with something like:
swapselect(:article,#art,:categories,Category.find(:all).map { |cat| [cat.name, cat.id] })
(I would tend to wrap that in a helper to make the call even cleaner)
One small gotcha is that for very long lists it can run a little slow in IE6 because there's quite a lot of appendChild calls in the js which is notorioulsy slow in IE6
Update: Apologies. This doesn't really answer your original question, which was specifically about the Rails 2.3 feature. The swapselect option is version independent and doesn't make use of newer Rails functionality.